From 55499a015eec3adadbde6ee9214890520be08111 Mon Sep 17 00:00:00 2001 From: Domenico Iezzi Date: Sat, 9 Dec 2017 10:06:34 +0100 Subject: [PATCH] Helper functions for response parsing --- gpapi/googleplay.py | 38 ++++++++++++++++++-------------------- gpapi/utils.py | 26 +++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/gpapi/googleplay.py b/gpapi/googleplay.py index 13af457..a2d0bcf 100644 --- a/gpapi/googleplay.py +++ b/gpapi/googleplay.py @@ -63,7 +63,6 @@ class GooglePlayAPI(object): self.deviceBuilder.device['simoperator'] = sim_operator if cell_operator is not None: self.deviceBuilder.device['celloperator'] = cell_operator - # save last response text for error logging def encrypt_password(self, login, passwd): """Encrypt the password using the google publickey, using @@ -298,32 +297,31 @@ class GooglePlayAPI(object): while remaining > 0 and nextPath is not None: currentPath = nextPath data = self.executeRequestApi2(currentPath) - if len(data.preFetch) > 0: + if utils.hasPrefetch(data): response = data.preFetch[0].response else: response = data - if response.payload.HasField('searchResponse'): + if utils.hasSearchResponse(response.payload): # we still need to fetch the first page, so go to # next loop iteration without decrementing counter nextPath = response.payload.searchResponse.nextPageUrl continue - - if len(response.payload.listResponse.cluster) == 0: - # strange behaviour, probably due to - # expired token - raise LoginError('Unexpected behaviour, probably expired ' - 'token') - cluster = response.payload.listResponse.cluster[0] - if len(cluster.doc) == 0: - print('No results for query %s' % query) - break - if cluster.doc[0].containerMetadata.nextPageUrl != "": - nextPath = cluster.doc[0].containerMetadata.nextPageUrl - else: - nextPath = None - apps = list(chain.from_iterable([doc.child for doc in cluster.doc])) - output += list(map(utils.fromDocToDictionary, apps)) - remaining -= len(apps) + if utils.hasListResponse(response.payload): + cluster = response.payload.listResponse.cluster + if len(cluster) == 0: + # strange behaviour, probably due to expired token + raise LoginError('Unexpected behaviour, probably expired ' + 'token') + cluster = cluster[0] + if len(cluster.doc) == 0: + break + if cluster.doc[0].containerMetadata.nextPageUrl != "": + nextPath = cluster.doc[0].containerMetadata.nextPageUrl + else: + nextPath = None + apps = list(chain.from_iterable([doc.child for doc in cluster.doc])) + output += list(map(utils.fromDocToDictionary, apps)) + remaining -= len(apps) if len(output) > nb_result: output = output[:nb_result] diff --git a/gpapi/utils.py b/gpapi/utils.py index bfc4b3d..271ef5f 100644 --- a/gpapi/utils.py +++ b/gpapi/utils.py @@ -1,9 +1,9 @@ import struct import sys +from . import googleplay_pb2 VERSION = sys.version_info[0] - def fromDocToDictionary(app): return {"docId": app.docid, "title": app.title, @@ -68,3 +68,27 @@ def toBigInt(byteArray): decoded = struct.unpack("B", value)[0] out = out | decoded << key * 8 return out + +def hasPrefetch(response): + if type(response) is not googleplay_pb2.ResponseWrapper: + return False + try: + return response.HasField('preFetch') + except ValueError: + return False + +def hasListResponse(payload): + if type(payload) is not googleplay_pb2.Payload: + return False + try: + return payload.HasField('listResponse') + except ValueError: + return False + +def hasSearchResponse(payload): + if type(payload) is not googleplay_pb2.Payload: + return False + try: + return payload.HasField('searchResponse') + except ValueError: + return False