def test_request_without_login(self, valid_credentials_path): # Simulate a request without the token generated during login. playstore = Playstore(valid_credentials_path) del playstore.auth_token with pytest.raises(SystemExit) as err: playstore._execute_request('ignore') assert err.value.code == 1
def on_start_download(package_name): if package_name_regex.match(package_name): try: api = Playstore(credentials_location) try: app = api.app_details(package_name).docV2 except AttributeError: emit('download_bad_package', 'Unable to retrieve application with package name "{0}"'.format(package_name)) return details = { 'package_name': app.docid, 'title': app.title, 'creator': app.creator } downloaded_apk_file_path = os.path.join( downloaded_apk_location, re.sub(r'[^\w\-_.\s]', '_', '{0} by {1} - {2}.apk'.format(details['title'], details['creator'], details['package_name']))) for progress in api.silent_download_with_progress(details['package_name'], downloaded_apk_file_path): emit('download_progress', progress) logger.info('The application was downloaded and saved to "{0}"'.format(downloaded_apk_file_path)) emit('download_success', 'The application was successfully downloaded') except Exception as e: emit('download_error', str(e)) else: emit('download_error', 'Please specify a valid package name')
def test_request_without_login(self, valid_credentials_path): # Simulate a request without the token generated during login. playstore = Playstore(valid_credentials_path) del playstore.auth_token with pytest.raises(RuntimeError): # noinspection PyProtectedMember playstore._execute_request("ignore")
def main(): # Use the private credentials for this script. api = Playstore( os.path.join( os.path.dirname(os.path.realpath(__file__)), os.path.pardir, "private_credentials.json", ) ) # Get the categories in the Google Play Store. res = api.protobuf_to_dict(api.get_store_categories())["category"] store_categories = set( map(lambda x: parse_qs(urlparse(x["dataUrl"]).query)["cat"][0], res) ) # Get the top top_num free apps in each category. top_num = 100 for cat in store_categories: doc = api.list_app_by_category(cat, "apps_topselling_free", top_num).doc[0] for app in doc.child if doc.docid else doc.child[0].child: downloads = app.details.appDetails.numDownloads rating = app.aggregateRating.starRating # Print package name, category, number of downloads and rating. print(f"{app.docid}|{cat}|{downloads}|{rating}")
def main(): args = get_cmd_args() # Make sure to use a valid json file with the credentials. api = Playstore(args.credentials.strip(' \'"')) try: # Get the application details. app = api.app_details(args.package.strip(' \'"')).docV2 except AttributeError: print('Error when downloading "{0}". Unable to get app\'s details.'. format(args.package.strip(' \'"'))) sys.exit(1) details = { 'package_name': app.docid, 'title': app.title, 'creator': app.creator } if args.out.strip(' \'"') == downloaded_apk_default_location: # The downloaded apk will be saved in the Downloads folder (created in the same folder as this script). downloaded_apk_file_path = os.path.join( os.path.dirname(os.path.realpath(__file__)), downloaded_apk_default_location, re.sub( '[^\w\-_.\s]', '_', '{0} by {1} - {2}.apk'.format(details['title'], details['creator'], details['package_name']))) else: # The downloaded apk will be saved in the location chosen by the user. downloaded_apk_file_path = os.path.abspath(args.out.strip(' \'"')) # If it doesn't exist, create the directory where to save the downloaded apk. if not os.path.exists(os.path.dirname(downloaded_apk_file_path)): os.makedirs(os.path.dirname(downloaded_apk_file_path)) if args.tag and args.tag.strip(' \'"'): # If provided, prepend the specified tag to the file name. downloaded_apk_file_path = os.path.join( os.path.dirname(downloaded_apk_file_path), '[{0}] {1}'.format(args.tag.strip(' \'"'), os.path.basename(downloaded_apk_file_path))) # The download of the additional .obb files is optional. if args.blobs: success = api.download(details['package_name'], downloaded_apk_file_path, download_obb=True) else: success = api.download(details['package_name'], downloaded_apk_file_path, download_obb=False) if not success: print('Error when downloading "{0}".'.format(details['package_name'])) sys.exit(1)
def main(arg): args = arg apk_map = get_apk_version_map() # Make sure to use a valid json file with the credentials. api = Playstore(args.credentials.strip(' \'"')) try: # Get the application details. app = api.app_details(args.package.strip(' \'"')).docV2 if arg.package in apk_map: if int(apk_map[arg.package]) >= app.details.appDetails.versionCode: print( "------------The same version of the apk already exists------------" ) return except AttributeError: print('Error when downloading "{0}". Unable to get app\'s details.'. format(args.package.strip(' \'"'))) return details = { 'package_name': app.docid, 'title': app.title, 'creator': app.creator } if args.out.strip(' \'"') == downloaded_apk_default_location: # The downloaded apk will be saved in the Downloads folder (created in the same folder as this script). downloaded_apk_file_path = os.path.join( os.path.dirname(os.path.realpath(__file__)), downloaded_apk_default_location, re.sub( '[^\w\-_.\s]', '_', '{0}-{1}.apk'.format(details['package_name'], app.details.appDetails.versionCode))) else: # The downloaded apk will be saved in the location chosen by the user. downloaded_apk_file_path = os.path.abspath(args.out.strip(' \'"')) downloaded_apk_file_path = os.path.join( os.path.dirname(os.path.realpath(__file__)), downloaded_apk_file_path, re.sub( '[^\w\-_.\s]', '_', '{0}-{1}.apk'.format(details['package_name'], app.details.appDetails.versionCode))) print("The APK save path is ", downloaded_apk_file_path) # If it doesn't exist, create the directory where to save the downloaded apk. if not os.path.exists(os.path.dirname(downloaded_apk_file_path)): os.makedirs(os.path.dirname(downloaded_apk_file_path)) success = api.download(details['package_name'], downloaded_apk_file_path) if not success: print('Error when downloading "{0}".'.format(details['package_name'])) time.sleep(10) return
def process(package_name): if package_name_regex.match(package_name): try: api = Playstore("", True) try: app = api.app_details(package_name).docV2 except AttributeError: logger.error( f"Unable to retrieve application with " f"package name '{package_name}'", ) return jsonify({ "package": package_name, "status": "not valid" }), 400 details = { "package_name": app.docid, "title": app.title, "creator": app.creator, "version_code": app.details.appDetails.versionCode, "version": app.details.appDetails.versionString, } filename = "%s_%s(%s).apk" % (details['package_name'], details['version'], details['version_code']) downloaded_apk_file_path = os.path.join( downloaded_apk_location, filename, ) success = api.download(details["package_name"], downloaded_apk_file_path, False, False, False) if not success: logger.critical( f"Error when downloading '{details['package_name']}'") return jsonify({ "package": package_name, "status": "Error when downloading" }), 400 return { "package": details['package_name'], "filename": filename, "version": details['version'], "version_code": details['version_code'] } except Exception as e: logger.critical(f"Error during the download: {e}") abort(500) else: logger.critical("Please specify a valid package name") abort(400, description='Not valid package')
def main(): # Use the private credentials for this script. api = Playstore( os.path.join( os.path.dirname(os.path.realpath(__file__)), os.path.pardir, "private_credentials.json", )) # This list has to contain the exact developer(s) name(s). developer_list = ["Spotify Ltd.", "WhatsApp Inc.", "Mozilla"] for developer in developer_list: for package_name in api.list_app_by_developer(developer): # Print package name and developer name. print(f"{package_name}|{developer}")
def on_start_download(package_name): if package_name_regex.match(package_name): try: api = Playstore(credentials_location) try: app = api.app_details(package_name).docV2 except AttributeError: emit( "download_bad_package", "Unable to retrieve application with package name '{0}'". format(package_name), ) return details = { "package_name": app.docid, "title": app.title, "creator": app.creator, } downloaded_apk_file_path = os.path.join( downloaded_apk_location, re.sub( r"[^\w\-_.\s]", "_", "{0} by {1} - {2}.apk".format(details["title"], details["creator"], details["package_name"]), ), ) # noinspection PyProtectedMember for progress in api._download_with_progress( details["package_name"], downloaded_apk_file_path): emit("download_progress", progress) logger.info( "The application was downloaded and saved to '{0}'".format( downloaded_apk_file_path)) emit("download_success", "The application was successfully downloaded") except Exception as e: emit("download_error", str(e)) else: emit("download_error", "Please specify a valid package name")
def check_url(self, widget): thread.submit(self.check) def check(self): package = self.input_address.get_text() if package != '': data = ApiData(package) info = data.details self.label_package.set_text(info['package_name']) self.label_title.set_text(info['title']) self.label_developer.set_text(info['creator']) if data.icon == True: self.apk_image.set_from_file('apk_icon.png') else: pass if __name__ == '__main__': try: api = Playstore(credentials_default_location) except: print("Connect to Internet") thread = ThreadPoolExecutor(1) win = Downloader() win.window.connect("delete_event", Gtk.main_quit) win.window.show_all() Gtk.main()
class PlaystoreClient: def __init__(self, playstore_client_configuration): credentials_file_path = ( playstore_client_configuration.get_credendials_file_path()) self.api = Playstore(credentials_file_path.strip(" '\"")) def download( self, package_name, file_path="Downloads", tag=None, blobs=False, split_apks=False, ): details = self.get_app_details(package_name) downloaded_apk_file_path = self._prepare_file_path_if_does_not_exist( file_path, details, tag) success = self.api.download( details["package_name"], downloaded_apk_file_path, download_obb=True if blobs else False, download_split_apks=True if split_apks else False, ) if not success: raise RuntimeError( f"Error when downloading '{details['package_name']}'") def get_app_details(self, package_name): stripped_package_name = package_name.strip(" '\"") try: # Get the application details. app = self.api.app_details(stripped_package_name).docV2 except AttributeError: raise RuntimeError( f"Error when downloading '{stripped_package_name}': unable to get app's details" ) details = { "package_name": app.docid, "title": app.title, "creator": app.creator, } return details def _prepare_file_path_if_does_not_exist(self, file_path, details, tag): # The downloaded apk will be saved in the location chosen by the user. downloaded_apk_file_path = os.path.abspath(file_path.strip(" '\"")) # If it doesn't already exist, create the directory where to save the # downloaded apk. if not os.path.isdir(os.path.dirname(downloaded_apk_file_path)): os.makedirs(os.path.dirname(downloaded_apk_file_path), exist_ok=True) if tag and tag.strip(" '\""): # If provided, prepend the specified tag to the file name. stripped_tag = tag.strip(" '\"") downloaded_apk_file_path = os.path.join( os.path.dirname(downloaded_apk_file_path), f"[{stripped_tag}] {os.path.basename(downloaded_apk_file_path)}", ) return downloaded_apk_file_path
def test_corrupted_configuration(self, corrupted_configuration_path): with pytest.raises(json.decoder.JSONDecodeError): Playstore(corrupted_configuration_path)
def main(): args = get_cmd_args() try: # Make sure to use a valid json file with the credentials. api = Playstore(args.credentials.strip(" '\"")) stripped_package_name = args.package.strip(" '\"") try: # Get the application details. app = api.app_details(stripped_package_name).docV2 except AttributeError: logger.critical( f"Error when downloading '{stripped_package_name}': unable to " f"get app's details") sys.exit(1) details = { "package_name": app.docid, "title": app.title, "creator": app.creator, } if args.out.strip(" '\"") == downloaded_apk_default_location: # The downloaded apk will be saved in the Downloads folder (created in the # same folder as this script). downloaded_apk_file_path = os.path.join( downloaded_apk_default_location, re.sub( r"[^\w\-_.\s]", "_", f"{details['title']} by {details['creator']} - " f"{details['package_name']}.apk", ), ) else: # The downloaded apk will be saved in the location chosen by the user. downloaded_apk_file_path = os.path.abspath(args.out.strip(" '\"")) # If it doesn't already exist, create the directory where to save the # downloaded apk. if not os.path.isdir(os.path.dirname(downloaded_apk_file_path)): os.makedirs(os.path.dirname(downloaded_apk_file_path), exist_ok=True) if args.tag and args.tag.strip(" '\""): # If provided, prepend the specified tag to the file name. stripped_tag = args.tag.strip(" '\"") downloaded_apk_file_path = os.path.join( os.path.dirname(downloaded_apk_file_path), f"[{stripped_tag}] {os.path.basename(downloaded_apk_file_path)}", ) # The download of the additional files is optional. success = api.download( details["package_name"], downloaded_apk_file_path, download_obb=True if args.blobs else False, download_split_apks=True if args.split_apks else False, ) if not success: logger.critical( f"Error when downloading '{details['package_name']}'") sys.exit(1) except Exception as ex: logger.critical(f"Error during the download: {ex}") sys.exit(1)
def test_bad_credentials(self, wrong_credentials_path): with pytest.raises(RuntimeError): Playstore(wrong_credentials_path)
def test_incomplete_configuration(self, incomplete_configuration_path): with pytest.raises(KeyError): Playstore(incomplete_configuration_path)
def test_missing_configuration(self): with pytest.raises(SystemExit) as err: Playstore(MISSING_CONFIGURATION_FILE, debug=True) assert err.value.code == 1
def test_missing_configuration(self): with pytest.raises(FileNotFoundError): Playstore(MISSING_CONFIGURATION_FILE)
def test_bad_credentials(self, wrong_credentials_path): with pytest.raises(SystemExit) as err: Playstore(wrong_credentials_path) assert err.value.code == 1
def __init__(self, playstore_client_configuration): credentials_file_path = ( playstore_client_configuration.get_credendials_file_path()) self.api = Playstore(credentials_file_path.strip(" '\""))
def main(): args = get_cmd_args() credential = { "USERNAME": os.environ["APP_USERNAME"], "PASSWORD": os.environ["APP_PASSWORD"], "ANDROID_ID": os.environ["APP_ANDROID_ID"], "LANG_CODE": os.environ["APP_LANG_CODE"], "LANG": os.environ["APP_LANG_CODE"] } try: api = Playstore(credential) stripped_package_name = os.environ["APP_PACKAGE"] try: app = api.app_details(stripped_package_name).docV2 except AttributeError: logger.critical( f"Error when downloading '{stripped_package_name}': unable to " f"get app's details") sys.exit(1) details = { "package_name": app.docid, "title": app.title, "creator": app.creator, } if args.out.strip(" '\"") == downloaded_apk_default_location: downloaded_apk_file_path = os.path.join( downloaded_apk_default_location, re.sub( r"[^\w\-_.\s]", "_", f"{details['title']} by {details['creator']} - " f"{details['package_name']}.apk", ), ) else: downloaded_apk_file_path = os.path.abspath(args.out.strip(" '\"")) if not os.path.isdir(os.path.dirname(downloaded_apk_file_path)): os.makedirs(os.path.dirname(downloaded_apk_file_path), exist_ok=True) if args.tag and args.tag.strip(" '\""): stripped_tag = args.tag.strip(" '\"") downloaded_apk_file_path = os.path.join( os.path.dirname(downloaded_apk_file_path), f"[{stripped_tag}] {os.path.basename(downloaded_apk_file_path)}", ) success = api.download( details["package_name"], downloaded_apk_file_path, download_obb=True if args.blobs else False, download_split_apks=True if args.split_apks else False, ) if not success: logger.critical( f"Error when downloading '{details['package_name']}'") sys.exit(1) except Exception as ex: logger.critical(f"Error during the download: {ex}") sys.exit(1)
def test_incomplete_configuration(self, incomplete_configuration_path): with pytest.raises(SystemExit) as err: Playstore(incomplete_configuration_path) assert err.value.code == 1
def test_corrupted_configuration(self, corrupted_configuration_path): with pytest.raises(SystemExit) as err: Playstore(corrupted_configuration_path) assert err.value.code == 1
def playstore(valid_credentials_path): return Playstore(valid_credentials_path)
def main(): args = get_cmd_args() try: # Make sure to use a valid json file with the credentials. api = Playstore(args.credentials.strip(" '\"")) try: # Get the application details. app = api.app_details(args.package.strip(" '\"")).docV2 except AttributeError: logger.critical( "Error when downloading '{0}': unable to get app's details". format(args.package.strip(" '\""))) sys.exit(1) details = { "package_name": app.docid, "title": app.title, "creator": app.creator, } if args.out.strip(" '\"") == downloaded_apk_default_location: # The downloaded apk will be saved in the Downloads folder (created in the # same folder as this script). downloaded_apk_file_path = os.path.join( os.path.dirname(os.path.realpath(__file__)), downloaded_apk_default_location, re.sub( r"[^\w\-_.\s]", "_", "{0} by {1} - {2}.apk".format(details["title"], details["creator"], details["package_name"]), ), ) else: # The downloaded apk will be saved in the location chosen by the user. downloaded_apk_file_path = os.path.abspath(args.out.strip(" '\"")) # If it doesn't already exist, create the directory where to save the # downloaded apk. if not os.path.isdir(os.path.dirname(downloaded_apk_file_path)): os.makedirs(os.path.dirname(downloaded_apk_file_path), exist_ok=True) if args.tag and args.tag.strip(" '\""): # If provided, prepend the specified tag to the file name. downloaded_apk_file_path = os.path.join( os.path.dirname(downloaded_apk_file_path), "[{0}] {1}".format(args.tag.strip(" '\""), os.path.basename(downloaded_apk_file_path)), ) # The download of the additional .obb files is optional. success = api.download( details["package_name"], downloaded_apk_file_path, download_obb=True if args.blobs else False, ) if not success: logger.critical("Error when downloading '{0}'".format( details["package_name"])) sys.exit(1) except Exception as ex: logger.critical("Error during the download: {0}".format(ex)) sys.exit(1)