예제 #1
0
def publish_screenshot_sets(
    access_token: AccessToken,
    localization_dir: str,
    localization_id: str,
):
    """Publish the screenshot sets from assets on disk."""
    screenshots_dir = os.path.join(localization_dir, "screenshots")
    if not os.path.isdir(screenshots_dir):
        print_clr(
            f"    No screenshots: directory {colorama.Fore.CYAN}{screenshots_dir}{colorama.Fore.RESET} not found.",
        )
        return

    screenshot_sets = appstore.get_screenshot_sets(
        localization_id=localization_id, access_token=access_token)

    asset_display_types = [
        x for x in os.listdir(screenshots_dir)
        if os.path.isdir(os.path.join(screenshots_dir, x))
    ]

    # Create new display types
    loc_display_types = [
        x["attributes"]["screenshotDisplayType"] for x in screenshot_sets
    ]
    new_display_types = [
        x for x in asset_display_types if x not in loc_display_types
    ]
    for display_type in new_display_types:
        print_media_set_status(display_type, colorama.Fore.YELLOW,
                               "creating display type")
        screenshot_set = appstore.create_screenshot_set(
            localization_id=localization_id,
            display_type=display_type,
            access_token=access_token,
        )
        screenshot_sets.append(screenshot_set)

    for screenshot_set in screenshot_sets:
        screenshot_set_id = screenshot_set["id"]
        display_type = screenshot_set["attributes"]["screenshotDisplayType"]
        screenshot_set_dir = os.path.join(screenshots_dir, display_type)

        # Delete removed display types
        if not os.path.isdir(screenshot_set_dir):
            print_media_set_status(display_type, colorama.Fore.RED,
                                   "deleting display type")
            appstore.delete_screenshot_set(screenshot_set_id=screenshot_set_id,
                                           access_token=access_token)
            continue

        # Publish
        publish_screenshots(
            access_token=access_token,
            screenshot_set_dir=screenshot_set_dir,
            screenshot_set_id=screenshot_set_id,
            display_type=display_type,
        )
예제 #2
0
def publish_preview_sets(
    access_token: AccessToken,
    localization_dir: str,
    localization_id: str,
):
    """Publish the previews sets from assets on disk."""
    previews_dir = os.path.join(localization_dir, "previews")
    if not os.path.isdir(previews_dir):
        print_clr(
            f"    No previews: directory {colorama.Fore.CYAN}{previews_dir}{colorama.Fore.RESET} not found.",
        )
        return

    preview_sets = appstore.get_preview_sets(localization_id=localization_id,
                                             access_token=access_token)

    asset_display_types = [
        x for x in os.listdir(previews_dir)
        if os.path.isdir(os.path.join(previews_dir, x))
    ]

    # Create new display types
    loc_preview_types = [x["attributes"]["previewType"] for x in preview_sets]
    new_preview_types = [
        x for x in asset_display_types if x not in loc_preview_types
    ]
    for preview_type in new_preview_types:
        print_media_set_status(preview_type, colorama.Fore.YELLOW,
                               "creating preview type")
        preview_set = appstore.create_preview_set(
            localization_id=localization_id,
            preview_type=preview_type,
            access_token=access_token,
        )
        preview_sets.append(preview_set)

    for preview_set in preview_sets:
        preview_set_id = preview_set["id"]
        preview_type = preview_set["attributes"]["previewType"]
        preview_set_dir = os.path.join(previews_dir, preview_type)

        # Delete removed display types
        if not os.path.isdir(preview_set_dir):
            print_media_set_status(preview_type, colorama.Fore.RED,
                                   "deleting preview type")
            appstore.delete_preview_set(preview_set_id=preview_set_id,
                                        access_token=access_token)
            continue

        # Publish
        publish_previews(
            access_token=access_token,
            preview_set_dir=preview_set_dir,
            preview_set_id=preview_set_id,
            display_type=preview_type,
        )
예제 #3
0
def publish(
    access_token: AccessToken,
    asset_dir: str,
    app_id: str,
    bundle_id: str,
    platform: Union[appstore.Platform, str],  # pylint: disable=unsubscriptable-object
    version_string: str,
    update_version_string: bool,
    allow_create_version: bool = True,
    allow_create_locale: bool = True,
    allow_delete_locale: bool = True,
):
    """Publish all the app meta data app store, using any editable app versions found.
    If none are found, a new version can be created for the specified target platform."""
    print_clr("Publishing assets from directory: ",
              colorama.Fore.CYAN + asset_dir)

    # Application directory
    app_dir = os.path.join(asset_dir, bundle_id)
    if not os.path.isdir(app_dir):
        raise FileNotFoundError(
            f"App directory {colorama.Fore.CYAN}{app_dir}{colorama.Fore.RESET} not found. "
        )

    publish_version(
        access_token=access_token,
        app_dir=app_dir,
        app_id=app_id,
        bundle_id=bundle_id,
        platform=platform,
        version_string=version_string,
        update_version_string=update_version_string,
        allow_create_version=allow_create_version,
        allow_create_locale=allow_create_locale,
        allow_delete_locale=allow_delete_locale,
    )
    publish_info(
        access_token=access_token,
        app_dir=app_dir,
        app_id=app_id,
        bundle_id=bundle_id,
        platform=platform,
    )
    print_clr(colorama.Fore.GREEN + "Publish complete")
예제 #4
0
def download(
    access_token: AccessToken,
    asset_dir: str,
    app_id: str,
    bundle_id: str,
    platforms: appstore.PlatformList,
    version_states: appstore.VersionStateList = tuple(appstore.VersionState),
    overwrite: bool = False,
):
    """Download all the app meta data to the local app directory."""
    app_dir = os.path.join(asset_dir, bundle_id)

    print_clr(
        f"{colorama.Fore.CYAN}{bundle_id} ",
        f"{colorama.Fore.BLUE}{app_id} ",
        f"-> ",
        f"{colorama.Fore.CYAN}{app_dir}",
    )

    # App
    if os.path.isdir(app_dir) and not overwrite:
        raise FileExistsError(
            f"App directory {colorama.Fore.CYAN}{app_dir}{colorama.Fore.RESET} already exists. "
            +
            "Specify '--overwrite' if you wish to force downloading to an existing directory."
        )

    download_info(
        access_token=access_token,
        app_dir=app_dir,
        app_id=app_id,
        bundle_id=bundle_id,
        version_states=version_states,
    )
    download_version(
        access_token=access_token,
        app_dir=app_dir,
        app_id=app_id,
        bundle_id=bundle_id,
        platforms=platforms,
        version_states=version_states,
    )
    print_clr(colorama.Fore.GREEN + "Download complete")
예제 #5
0
def list_categories(
    access_token: AccessToken,
    platforms: appstore.PlatformList,
    verbosity: Verbosity = Verbosity.SHORT,
):
    """List the appstore's heirachry of categories and subcategories."""
    categories = appstore.get_categories(access_token=access_token,
                                         platforms=platforms)
    categories.sort(key=lambda x: x["id"])

    if verbosity == Verbosity.SHORT:
        for x in categories:
            print_clr(
                x["id"],
                colorama.Fore.LIGHTBLACK_EX +
                f' {{{",".join(x["attributes"]["platforms"])}}}',
            )

            for sub in x["relationships"]["subcategories"]["data"]:
                print_clr(colorama.Style.DIM + f'  {sub["id"]}')

    else:
        print(json_term(categories))
예제 #6
0
def list_previews(
        access_token: AccessToken,
        app_id: str,
        platforms: appstore.PlatformList,
        states: appstore.VersionStateList,
        version_limit: Optional[int],  # pylint: disable=unsubscriptable-object
):
    """List previews for each preview set of each app version."""
    logging.info(clr(colorama.Fore.GREEN + "app_id: ", str(app_id)))

    versions = appstore.get_versions(app_id=app_id,
                                     access_token=access_token,
                                     platforms=platforms,
                                     states=states)
    for version in versions[:version_limit]:
        version_id = version["id"]
        version_state = version["attributes"]["appStoreState"]
        print_clr(
            f"{colorama.Fore.GREEN}version: {colorama.Fore.BLUE}{version_id} {version_state}"
        )

        localizations = appstore.get_version_localizations(
            version_id=version_id, access_token=access_token)

        localization_ids = (l["id"] for l in localizations)
        for loc_id in localization_ids:
            preview_sets = appstore.get_preview_sets(localization_id=loc_id,
                                                     access_token=access_token)
            print_clr(
                f"{colorama.Fore.GREEN}loc_id {loc_id}: ",
                f"Found {colorama.Fore.CYAN}{len(preview_sets)}{colorama.Fore.RESET} preview sets.",
            )

            for preview_set in preview_sets:
                preview_set_id = preview_set["id"]
                preview_type = preview_set["attributes"]["previewType"]
                preview_set = appstore.get_previews(
                    preview_set_id=preview_set_id, access_token=access_token)
                print_clr(f"{colorama.Fore.GREEN}previewType: ", preview_type)
                print(json_term(preview_set))
예제 #7
0
def publish_info(
        access_token: AccessToken,
        app_dir: str,
        app_id: str,
        bundle_id: str,
        platform: Union[appstore.Platform, str],  # pylint: disable=unsubscriptable-object
):
    # Get Infos
    infos = appstore.get_infos(
        app_id=app_id,
        access_token=access_token,
        states=appstore.editable_version_states,
    )
    print_clr(
        f"Found {colorama.Fore.CYAN}{len(infos)}{colorama.Fore.RESET} editable app infos."
    )

    asset_locales = [
        x for x in os.listdir(app_dir)
        if os.path.isdir(os.path.join(app_dir, x))
    ]

    for info in infos:
        info_id = info["id"]
        version_state = info["attributes"]["appStoreState"]

        print_clr(
            colorama.Fore.GREEN + "AppInfo ",
            colorama.Fore.BLUE + f"{info_id} ",
            colorama.Fore.CYAN + f"{version_state}",
        )

        localizations = appstore.get_info_localizations(
            info_id=info_id, access_token=access_token)

        # create new localizations
        info_locales = [loc["attributes"]["locale"] for loc in localizations]
        new_locales = [x for x in asset_locales if x not in info_locales]
        for locale in new_locales:
            print_locale_status(locale, colorama.Fore.LIGHTBLACK_EX,
                                "locale creation not allowed")

        for loc in localizations:
            loc_id = loc["id"]
            loc_attr = loc["attributes"]
            locale = loc_attr["locale"]
            loc_dir = os.path.join(app_dir, locale)

            # Delete removed locales
            if not os.path.isdir(loc_dir):
                print_locale_status(locale, colorama.Fore.LIGHTBLACK_EX,
                                    "locale deletion not allowed")
                continue

            # Normalize all attribute values to strings
            for key in appstore.InfoLocalizationAttributes.__annotations__.keys(
            ):
                if loc_attr[key] is None:
                    loc_attr[key] = ""

            # Load local data from disk
            asset_loc_data: appstore.InfoLocalizationAttributes = {}
            for key in appstore.InfoLocalizationAttributes.__annotations__.keys(
            ):
                path = os.path.join(loc_dir, key + ".txt")
                content = read_txt_file(path)
                if content is not None:
                    asset_loc_data[key] = content  # type: ignore

            # Only need to update if there are differences
            loc_diff_keys = [
                key for key, value in asset_loc_data.items()
                if value is not None and value != loc_attr[key]
            ]
            if len(loc_diff_keys) > 0:
                print_locale_status(
                    locale,
                    colorama.Fore.CYAN,
                    f"updating app info {colorama.Fore.CYAN}{colorama.Style.DIM}{loc_diff_keys}",
                )
                appstore.update_info_localization(
                    info_localization_id=loc_id,
                    info_localization_attributes=asset_loc_data,
                    access_token=access_token,
                )
            else:
                print_locale_status(locale, colorama.Fore.CYAN,
                                    "no changes in app settings")
예제 #8
0
def publish_version(
    access_token: AccessToken,
    app_dir: str,
    app_id: str,
    bundle_id: str,
    platform: Union[appstore.Platform, str],  # pylint: disable=unsubscriptable-object
    version_string: str,
    update_version_string: bool,
    allow_create_version: bool = True,
    allow_create_locale: bool = True,
    allow_delete_locale: bool = True,
):
    # Get Versions
    versions = appstore.get_versions(
        app_id=app_id,
        access_token=access_token,
        platforms=[platform],
        states=appstore.editable_version_states,
    )
    print_clr(
        f"Found {colorama.Fore.CYAN}{len(versions)}{colorama.Fore.RESET} editable app versions ",
        f"for {colorama.Fore.CYAN}{platform}{colorama.Fore.RESET}.",
    )

    if len(versions) == 0 and allow_create_version:
        print(
            f"Creating new version: {colorama.Fore.BLUE}{version_string}{colorama.Fore.RESET}"
        )
        created_version = appstore.create_version(
            app_id=app_id,
            platform=platform,
            version_string=version_string,
            access_token=access_token,
        )
        versions.append(created_version)
    elif update_version_string:
        for v in versions:
            version_id = v["id"]
            version_state = v["attributes"]["appStoreState"]

            version_attributes: appstore.VersionAttributes = {
                "versionString": version_string,
            }
            print_clr(
                f"{colorama.Fore.GREEN}Version ",
                f"{colorama.Fore.BLUE}{version_state} ",
                f": updating version ",
                f"{colorama.Fore.CYAN}{version_attributes}",
            )

            appstore.update_version(
                version_id=version_id,
                version_attributes=version_attributes,
                access_token=access_token,
            )

    for v in versions:
        version_id = v["id"]
        version_state = v["attributes"]["appStoreState"]

        print_clr(
            f"{colorama.Fore.GREEN}Version ",
            f"{colorama.Fore.BLUE}{version_id} ",
            f"{colorama.Fore.CYAN}{version_state} ",
        )
        publish_version_localizations(
            access_token=access_token,
            app_dir=app_dir,
            version_id=version_id,
            allow_create_locale=allow_create_locale,
            allow_delete_locale=allow_delete_locale,
        )
예제 #9
0
def print_media_status(file_name: str, color: str, status: str):
    print_clr(f"      {color}{file_name}", f" - {status}")
예제 #10
0
def print_media_set_status(display_type: str, color: str, status: str):
    print_clr(f"    {color}{display_type}", f" - {status}")
예제 #11
0
def print_locale_status(locale: str, color: str, status: str):
    print_clr(f"  {color}{locale:5}", f" - {status}")
예제 #12
0
def print_version_status(version_state: str, platform: str, status: str):
    print_clr(
        f"{colorama.Fore.CYAN}{version_state} ",
        f"{colorama.Fore.CYAN + colorama.Style.DIM}{{{platform}}}",
        f" - {status}",
    )
예제 #13
0
def print_info_status(info_state: str, status: str):
    print_clr(f"{colorama.Fore.CYAN}{info_state}", f" - {status}")
예제 #14
0
def list_screenshots(
    access_token: AccessToken,
    app_id: str,
    platforms: appstore.PlatformList,
    states: appstore.VersionStateList,
    version_limit: Optional[int],  # pylint: disable=unsubscriptable-object
    verbosity: Verbosity = Verbosity.SHORT,
):
    """List screenhots for each screenshot set of each app version."""
    logging.info(clr(colorama.Fore.GREEN + "app_id: ", str(app_id)))

    versions = appstore.get_versions(app_id=app_id,
                                     access_token=access_token,
                                     platforms=platforms,
                                     states=states)
    for version in versions[:version_limit]:
        version_id = version["id"]
        version_state = version["attributes"]["appStoreState"]
        print_clr(
            f"{colorama.Fore.GREEN}{version_state} {colorama.Style.DIM}{version_id} "
        )

        localizations = appstore.get_version_localizations(
            version_id=version_id, access_token=access_token)

        for loc in localizations:
            loc_id = loc["id"]
            locale = loc["attributes"]["locale"]

            screenshot_sets = appstore.get_screenshot_sets(
                localization_id=loc_id, access_token=access_token)
            print_clr(
                f"{colorama.Fore.GREEN}{locale}: ",
                f"Found {colorama.Fore.CYAN}{len(screenshot_sets)}{colorama.Fore.RESET} screenshot sets.",
            )

            for screenshot_set in screenshot_sets:
                ss_set_id = screenshot_set["id"]
                ss_display_type = screenshot_set["attributes"][
                    "screenshotDisplayType"]
                screenshots = appstore.get_screenshots(
                    screenshot_set_id=ss_set_id, access_token=access_token)
                if verbosity == Verbosity.SHORT:
                    print_clr(colorama.Fore.CYAN + ss_display_type)
                    for x in screenshots:
                        print_clr(
                            f'  {colorama.Style.DIM}{x["attributes"]["assetDeliveryState"]["state"]:15}',
                            f'  {x["attributes"]["fileName"]}',
                        )
                    continue
                if verbosity == Verbosity.LONG:
                    screenshots = [
                        ({
                            "id":
                            x["id"],
                            "fileSize":
                            x["attributes"]["fileSize"],
                            "fileName":
                            x["attributes"]["fileName"],
                            "sourceFileChecksum":
                            x["attributes"]["sourceFileChecksum"],
                            "templateUrl":
                            x["attributes"]["imageAsset"]["templateUrl"],
                            "width":
                            x["attributes"]["imageAsset"]["width"],
                            "height":
                            x["attributes"]["imageAsset"]["height"],
                            "assetDeliveryState":
                            x["attributes"]["assetDeliveryState"]["state"],
                        } if x["attributes"]["assetDeliveryState"]["state"]
                         == appstore.MediaAssetState.COMPLETE else {
                             "id":
                             x["id"],
                             "fileSize":
                             x["attributes"]["fileSize"],
                             "fileName":
                             x["attributes"]["fileName"],
                             "sourceFileChecksum":
                             x["attributes"]["sourceFileChecksum"],
                             "assetDeliveryState":
                             x["attributes"]["assetDeliveryState"]["state"],
                         }) for x in screenshots
                    ]
                print(
                    json_term({
                        "screenshotDisplayType": ss_display_type,
                        "screenshots": screenshots,
                    }))