def get_related(self, browse_stream):
        """
        get the list of apps under the "more you might like" section under app details
        :param browse_stream: the link from the app details to request the list of related apps
        :return: a list of related apps and their details
        """

        headers = {
            'X-DFE-Device-Id': self.android_id,
            'X-DFE-Client-Id': 'am-android-google',
            'Accept-Encoding': '',
            'Host': 'android.clients.google.com',
            'Authorization': 'GoogleLogin Auth=' + self.auth,
            'User-Agent': MARKET_USER_AGENT
        }

        response = self.session.get(GOOGLE_FDFE_URL + "/" + browse_stream,
                                    params=None,
                                    headers=headers,
                                    allow_redirects=True)

        related_response = apkfetch_pb2.ResponseWrapper()
        related_response.ParseFromString(response.content)

        if not related_response:
            raise Exception('Could not get related apps for')
        if related_response.commands.displayErrorMessage != "":
            raise Exception('error getting related apps: ' +
                            related_response.commands.displayErrorMessage)
        return related_response.preFetch[0].response.payload.listResponse.doc[
            0]
    def get_download_url(self, package_name, version_code):
        """
        performs a GET request to get the download url of a specific app
        :param package_name: the app to get the download url from
        :param version_code: the version of the app to download
        :return: the download url
        """

        headers = {
            'X-DFE-Device-Id': self.android_id,
            'X-DFE-Client-Id': 'am-android-google',
            'Accept-Encoding': '',
            'Host': 'android.clients.google.com',
            'Authorization': 'GoogleLogin Auth=' + self.auth,
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
        }

        data = {'doc': package_name, 'ot': '1', 'vc': version_code}

        response = self.session.get(GOOGLE_DELIVERY_URL,
                                    params=data,
                                    verify=True,
                                    headers=headers,
                                    allow_redirects=True)

        delivery_response = apkfetch_pb2.ResponseWrapper()
        delivery_response.ParseFromString(response.content)

        if not delivery_response:
            raise Exception('Could not get download url for: ' + package_name)
        if delivery_response.commands.displayErrorMessage != "":
            raise Exception('error getting download url: ' +
                            delivery_response.commands.displayErrorMessage +
                            " for: " + package_name)
        return delivery_response.payload.deliveryResponse.appDeliveryData.downloadUrl
    def reviews(self, package_name, amount=50):
        """
        performs a GET request to get the reviews of a specific app
        :param package_name: the app to get reviews from
        :param amount: amount of reviews to get
        :return: a list of reviews
        """

        headers = {
            'X-DFE-Device-Id': self.android_id,
            'X-DFE-Client-Id': 'am-android-google',
            'Accept-Encoding': '',
            'Host': 'android.clients.google.com',
            'Authorization': 'GoogleLogin Auth=' + self.auth,
            'User-Agent': MARKET_USER_AGENT
        }

        params = {'doc': package_name, 'n': amount}
        response = self.session.get(GOOGLE_REVIEWS_URL,
                                    params=params,
                                    headers=headers,
                                    allow_redirects=True)

        review_response = apkfetch_pb2.ResponseWrapper()
        review_response.ParseFromString(response.content)

        if not review_response:
            raise Exception('Could not get reviews for: ' + package_name)
        if review_response.commands.displayErrorMessage != "":
            raise Exception('error getting reviews: ' +
                            review_response.commands.displayErrorMessage +
                            " for: " + package_name)
        return review_response.payload.reviewResponse.getResponse
    def details(self, package_name):
        """
        performs a GET request to get the details of a specific app
        :param package_name: the app to get details from
        :return: the details of the app
        """

        headers = {
            'X-DFE-Device-Id': self.android_id,
            'X-DFE-Client-Id': 'am-android-google',
            'Accept-Encoding': '',
            'Host': 'android.clients.google.com',
            'Authorization': 'GoogleLogin Auth=' + self.auth,
            'User-Agent': MARKET_USER_AGENT
        }

        params = {'doc': package_name}
        response = self.session.get(GOOGLE_DETAILS_URL,
                                    params=params,
                                    headers=headers,
                                    allow_redirects=True)

        details_response = apkfetch_pb2.ResponseWrapper()
        details_response.ParseFromString(response.content)
        details = details_response.payload.detailsResponse.docV2
        if not details:
            raise Exception('Could not get details for: ' + package_name)
        if details_response.commands.displayErrorMessage != "":
            raise Exception('error getting details: ' +
                            details_response.commands.displayErrorMessage +
                            " for: " + package_name)
        return details
Esempio n. 5
0
 def version(self, package_name):
     headers = {'X-DFE-Device-Id': self.androidid,
                'X-DFE-Client-Id': 'am-android-google',
                'Accept-Encoding': '',
                'Host': 'android.clients.google.com',
                'Authorization': 'GoogleLogin ' + self.auth}
     
     params = {'doc': package_name}
     response = self.session.get(GOOGLE_DETAILS_URL, params=params, headers=headers, allow_redirects=True)
     
     details_response = apkfetch_pb2.ResponseWrapper()
     details_response.ParseFromString(response.content)
     version = details_response.payload.detailsResponse.docV2.details.appDetails.versionCode
     if not version:
         raise RuntimeError('Could not get version-code')
     return version
Esempio n. 6
0
    def get_download_url(self, package_name, version_code):
        headers = {
            'X-DFE-Device-Id': self.androidid,
            'X-DFE-Client-Id': 'am-android-google',
            'Accept-Encoding': '',
            'Host': 'android.clients.google.com',
            'Authorization': 'GoogleLogin Auth=' + self.auth
        }

        data = {'doc': package_name, 'ot': '1', 'vc': version_code}

        response = self.session.get(GOOGLE_DELIVERY_URL,
                                    params=data,
                                    headers=headers,
                                    allow_redirects=True)
        delivery_response = apkfetch_pb2.ResponseWrapper()
        delivery_response.ParseFromString(response.content)
        url = delivery_response.payload.deliveryResponse.appDeliveryData.downloadUrl
        return url
Esempio n. 7
0
    def fetch(self, package_name, apk_fn=None):
        headers = {'X-DFE-Device-Id': self.androidid,
                   'X-DFE-Client-Id': 'am-android-google',
                   'Accept-Encoding': '',
                   'Host': 'android.clients.google.com',
                   'Authorization': 'GoogleLogin ' + self.auth}

        data = {'doc': package_name,
                'ot': '1',
                'vc': self.version(package_name),
                'tok': 'dummy-token'}
        response = self.session.post(GOOGLE_PURCHASE_URL, data=data, headers=headers, allow_redirects=True)

        # Extract URL from response
        buy_response = apkfetch_pb2.ResponseWrapper()
        buy_response.ParseFromString(response.content)
        url = buy_response.payload.buyResponse.purchaseStatusResponse.appDeliveryData.downloadUrl
        
        error = buy_response.commands.displayErrorMessage
        if error or not url:
            raise RuntimeError(error or 'Could not get download URL')
        
        # Extract MarketDA value        
        marketda = None
        for c in buy_response.payload.buyResponse.purchaseStatusResponse.appDeliveryData.downloadAuthCookie:
            if c.name == 'MarketDA':
                marketda = c.value

        response = self.session.get(url, headers={'User-Agent': DOWNLOAD_USER_AGENT}, 
                                    cookies={'MarketDA': marketda}, stream=True, allow_redirects=True)

        apk_fn = apk_fn or (package_name + '.apk')
        if os.path.exists(apk_fn):
            os.remove(apk_fn)

        with open(apk_fn, 'wb') as fp:
            for chunk in response.iter_content(chunk_size=5*1024): 
                if chunk:
                    fp.write(chunk)
                    fp.flush()

        return os.path.exists(apk_fn)