Exemple #1
0
 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
Exemple #2
0
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')
Exemple #3
0
 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")
Exemple #4
0
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}")
Exemple #5
0
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)
Exemple #6
0
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}")
Exemple #9
0
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")
Exemple #10
0
    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()
Exemple #11
0
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
Exemple #12
0
 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)
Exemple #14
0
 def test_bad_credentials(self, wrong_credentials_path):
     with pytest.raises(RuntimeError):
         Playstore(wrong_credentials_path)
Exemple #15
0
 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
Exemple #17
0
 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
Exemple #19
0
 def __init__(self, playstore_client_configuration):
     credentials_file_path = (
         playstore_client_configuration.get_credendials_file_path())
     self.api = Playstore(credentials_file_path.strip(" '\""))
Exemple #20
0
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)