bulkDetails: handle case when app doesn't exist

Now the function returns None if an app doesnt't exists. This does not
apply for details() function, which instead return a RequestError if the
app doesn't exist.
This commit is contained in:
Domenico Iezzi 2017-11-02 17:34:49 +01:00
parent 7678402f10
commit 25bfb4aaec
No known key found for this signature in database
GPG Key ID: 7AC94D5DDA2FB7EE
2 changed files with 30 additions and 8 deletions

View File

@ -204,6 +204,11 @@ class GooglePlayAPI(object):
raise LoginError("Auth token not found.") raise LoginError("Auth token not found.")
def _check_response_integrity(self, apps): def _check_response_integrity(self, apps):
"""Like described in issue #18, after some time it seems
that google invalidates the token. And the strange thing is that when
sending requests with an invalid token, it won't throw an error but
it returns empty responses. This is a function used to check if the
content returned is valid (usually a docId field is always present)"""
if any([a['docId'] == '' for a in apps]): if any([a['docId'] == '' for a in apps]):
raise LoginError('Unexpected behaviour, probably expired ' raise LoginError('Unexpected behaviour, probably expired '
'token') 'token')
@ -295,9 +300,15 @@ class GooglePlayAPI(object):
"""Get several apps details from a list of package names. """Get several apps details from a list of package names.
This is much more efficient than calling N times details() since it This is much more efficient than calling N times details() since it
requires only one request. requires only one request. If an item is not found it returns an empty object
instead of throwing a RequestError('Item not found') like the details() function
packageNames is a list of app ID (usually starting with 'com.').""" Args:
packageNames (list): a list of app IDs (usually starting with 'com.').
Returns:
a list of dictionaries containing docv1 data, or None
if the app doesn't exist"""
path = "bulkDetails" path = "bulkDetails"
req = googleplay_pb2.BulkDetailsRequest() req = googleplay_pb2.BulkDetailsRequest()
@ -307,9 +318,14 @@ class GooglePlayAPI(object):
data.decode("utf-8"), data.decode("utf-8"),
"application/x-protobuf") "application/x-protobuf")
response = message.payload.bulkDetailsResponse response = message.payload.bulkDetailsResponse
detailsList = [entry.doc for entry in response.entry] result = []
result = list(map(utils.fromDocToDictionary, detailsList)) for entry in response.entry:
self._check_response_integrity(result) if not entry.HasField('doc'):
result.append(None)
else:
appDetails = utils.fromDocToDictionary(entry.doc)
self._check_response_integrity([appDetails])
result.append(appDetails)
return result return result
def browse(self, cat=None, subCat=None): def browse(self, cat=None, subCat=None):

12
test.py
View File

@ -9,7 +9,6 @@ ap.add_argument('-p', '--password', dest='password', help='google password')
args = ap.parse_args() args = ap.parse_args()
testApps = ['org.mozilla.firefox']
server = GooglePlayAPI(debug=True) server = GooglePlayAPI(debug=True)
# LOGIN # LOGIN
@ -69,9 +68,16 @@ if not errorThrown:
# BULK DETAILS # BULK DETAILS
print('\nGetting bulkDetails for %s\n' % testApps[0]) testApps = ['org.mozilla.firefox', 'com.non.existing.app']
bulk = server.bulkDetails(testApps) bulk = server.bulkDetails(testApps)
print(bulk)
print('\nTesting behaviour for non-existing apps\n')
if bulk[1] is not None:
print('bulkDetails should return None for non-existing apps')
sys.exit(1)
print('\nResult from bulkDetails for %s\n' % testApps[0])
print(bulk[0])
# DETAILS # DETAILS
print('\nGetting details for %s\n' % testApps[0]) print('\nGetting details for %s\n' % testApps[0])