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, )
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, )
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")
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")
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))
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))
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")
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, )
def print_media_status(file_name: str, color: str, status: str): print_clr(f" {color}{file_name}", f" - {status}")
def print_media_set_status(display_type: str, color: str, status: str): print_clr(f" {color}{display_type}", f" - {status}")
def print_locale_status(locale: str, color: str, status: str): print_clr(f" {color}{locale:5}", f" - {status}")
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}", )
def print_info_status(info_state: str, status: str): print_clr(f"{colorama.Fore.CYAN}{info_state}", f" - {status}")
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, }))