commit 8f04d673d92091bd8f5d19e90f67b6ec0efdf058 Author: relikd Date: Tue Apr 2 21:54:37 2024 +0200 Initial diff --git a/README.md b/README.md new file mode 100755 index 0000000..937b3fb --- /dev/null +++ b/README.md @@ -0,0 +1,101 @@ +# IPA Archiver + +Scripts to download and unlock `.ipa` files for historical preservation. Every version of all the apps you ever purchased. + +Personal usage only. This is not intended for piracy. Apple anounced they will shutdown older software and this is my attempt at preserving what I have bought and be able to run it even if Apple decides to delete everything. + + +## Requirements + +You'll need: + +- Windows 7 PC (I have not tested a VM but if it detects your iDevice via USB then it should be ok) +- macOS device (to run the main scripts, maybe it can be done with Windows alone, haven't tested) +- iDevice (jailbroken) + + +### Windows + +- Install iTunes 12.6.5.3 [64bit](https://secure-appldnld.apple.com/itunes12/091-87819-20180912-69177170-B085-11E8-B6AB-C1D03409AD2A6/iTunes64Setup.exe) +(for completeness: [32bit](https://secure-appldnld.apple.com/itunes12/091-87820-20180912-69177170-B085-11E8-B6AB-C1D03409AD2A5/iTunesSetup.exe) though not needed) +- Install Python 3.8 +- Clone [NyaMisty/actions-iTunes-header](https://github.com/NyaMisty/actions-iTunes-header) or use the one provided with this repo. +- Compile [libimobiledevice](https://github.com/libimobiledevice/libimobiledevice) or download [iFred09/libimobiledevice-windows](https://github.com/iFred09/libimobiledevice-windows) or use the one provided with this repo. +- In your firewall, open TCP ports `8117` (step 5, below) and `9000` (step 4, below). +- Enable network sharing on your home directory (this is how macOS will access the files) + + +Instructions: + +1. Copy the `src_win` folder to windows. +2. If you have not done so already, patch iTunes with `src_win/actions-iTunes-header/workflow_helper/iTunesInstall/patch_itunes.py` +3. Start `iTunes` +4. Start `src_win/actions-iTunes-header/workflow_helper/iTunesDownload/get_header.py` +5. Start `src_win/win_server.py` +6. Connect your iDevice with Windows via USB + + +### iOS + +- Apply a jailbreak corresponding to your iOS version +- Install SSH & change password +- Generate and copy an SSH key file (without password) to the device + + +### macOS + +- Clone [NyaMisty/ipatool-py](https://github.com/NyaMisty/ipatool-py) or use the one provided with this repo. +- Connect to your network share (in Finder `Cmd+K` on `smb://your-pc`) +- Adjust your `config.ini` accordingly (see below) +- Edit your `~/.ssh/config` and add the iPad destination: + +``` +Host ipad + HostName 192.168.0.0 + User root + PreferredAuthentications publickey + IdentityFile ~/.ssh/ipad.private-key +``` + +You should be able to connect to the iPad just by typing `ssh ipad` (without password prompt). + + +## Config.ini + +- `itunes_server` & `win_server` should point to your Windows machine (with corresponding IP port) +- `ssh_cmd_crack`: the command used to launch the cracking (e.g. `Clutch`). Notice that we first remove all previous cracks. +- `ssh_cmd_sync`: Used to download the cracked apps. Notice that both commands just use "ipad" to connect to the device. +- `max_os`: most likely the iOS version running on your iDevice. +- `convert_binary_plist`: Turn this only on, if the Plist is somehow broken. We dont want to modify the app if we can avoid it. +- `sync_in`: same folder as `ssh_cmd_sync` will download into +- `sync_out`: network folder on your windows machine, same place where you copied your `src_win/queued` folder. +- `complete`: folder used to query new app ids. This is constantly updated before and after each app. E.g., `_versions.json` in each bundle-id dir. +- `download_fix`: download folder for IPA files. They remain there until they have been cracked. +- `download_tmp`: temporary folder for `ipatool-py`. Once an app is fully downloaded, the app moved to `download_fix` + + +## Usage + +1. You need to generate a history version list. Each app you download from iTunes has its history attached. You can, for example, download the latest version of an app via iTunes (Win) and run `./src_mac/extract_versions.py -m network-dir/to/*.ipa`. This will read all versions and extract them to the `done` directory. Note: the `-m` flag will move some of the IPA files if they are within the `max_os` range. Omit the flag if you want to keep the source files as is. +2. Your `complete` folder should now have a bunch of folders (one per app), each with a `_versions.json` file. Run `src_mac/download.py` to download all historic versions up until the last compatible iOS version as defined per config. +3. Run `src_mac/crack.py` to start the cracking process. You can run this in parallel to step 2. + + +## Known issues + +Both, the cracking and the download script will fail once in a while. + +`crack.py` fails: + +1. Most likely due to an (un)install timeout. I assume `libimobiledevice` to be the culprit. Just run the script again. (PS: In theory it should be fine to call the script in a while-true loop, though I wouldn't want to do it unsupervised.) + +2. If it fails with "no apps to crack", then the install probably failed. This can happen if you are not authorized to install the ipa. For example, if the `.sinf` is missing. Check you file or re-download it. + + +`download.py` can fail for many reasons: + +1. The most common one: one of the files inside the zip has unicode characters. Python will raise a `File name in directory X and header Y differ` exception. Where both are nearly identical except for some unprintable chars. As long as the filename is not ending on `/Info.plist`, you can unzip it manually, for example with [Keka](https://github.com/aonez/Keka). Duplicate the `.ipa` file and double click to extract it. This should create a folder which ends on either " 2" or " copy" (depending on how you copy the file). Then run repack manually: `./src_mac/repack_ipa.py download/*\ 2` (or " copy") + +2. If the file indeed ends on `/Info.plist`, then the unicode char is in the app name. Unzip as before, but before running repack, you have to move the `SC_Info/*.sinf` from the weird looking `Payload/*.app` to the non-broken app bundle. Right-click and "Show Package Contents". After you copied the file (there should be two now, `.sinf` and `.supp`), you can delte the weird looking app and continue with repack. + +3. In very rare cases, the previous error also breaks the whole download process. You may have to wait until the IPA is cracked or temporarily exclude it in the `download.py` script. Most likely you will need to manually update the `_versions.json`. diff --git a/config.ini b/config.ini new file mode 100755 index 0000000..2ad67f6 --- /dev/null +++ b/config.ini @@ -0,0 +1,16 @@ +[main] +itunes_server = http://192.168.0.0:9000 +win_server = http://192.168.0.0:8117 +ssh_cmd_crack = ssh ipad 'rm -rf /var/root/Documents/Cracked/; Clutch -a' +ssh_cmd_sync = scp 'ipad:/var/root/Documents/Cracked/*' ./dropbox_in +max_os = 5.1.1 + +[zip] +convert_binary_plist = false + +[paths] +sync_in = ./dropbox_in/ +sync_out = /Volumes/Users/usr/Desktop/src_win/queued +complete = ./done/ +download_fix = ./download/ +download_tmp = ./download_tmp/ diff --git a/src_ios/Clutch-1.3 b/src_ios/Clutch-1.3 new file mode 100644 index 0000000..b11dea2 Binary files /dev/null and b/src_ios/Clutch-1.3 differ diff --git a/src_ios/Clutch-2.0.4 b/src_ios/Clutch-2.0.4 new file mode 100644 index 0000000..caf65b7 Binary files /dev/null and b/src_ios/Clutch-2.0.4 differ diff --git a/src_mac/cfg.py b/src_mac/cfg.py new file mode 100755 index 0000000..9799513 --- /dev/null +++ b/src_mac/cfg.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +from configparser import ConfigParser +from pathlib import Path +import logging +import os + +os.chdir(Path(__file__).parent.parent) + +logging.basicConfig(format='%(asctime)s [%(levelname)s] %(message)s', + level=logging.INFO) +Log = logging.getLogger('main') + + +class Cfg(): + def __init__(self) -> None: + cfg = ConfigParser() + cfg.read('config.ini') + # [main] + self.itunes_server = cfg.get('main', 'itunes_server') + self.win_server = cfg.get('main', 'win_server') + self.ssh_cmd_crack = cfg.get('main', 'ssh_cmd_crack') + self.ssh_cmd_sync = cfg.get('main', 'ssh_cmd_sync') + self.max_os = cfg.get('main', 'max_os') + # [zip] + self.convert_plist = cfg.getboolean('zip', 'convert_binary_plist') + # [paths] + self.sync_in = Path(cfg.get('paths', 'sync_in')) + self.sync_out = Path(cfg.get('paths', 'sync_out')) + self.completed = Path(cfg.get('paths', 'complete')) + self.download_fix = Path(cfg.get('paths', 'download_fix')) + self.download_tmp = Path(cfg.get('paths', 'download_tmp')) + # config validation + for path in [self.sync_in, self.sync_out, self.completed]: + if not path.exists(): + raise FileNotFoundError(f'Directory "{path}" does not exist.') + # create dirs + self.download_fix.mkdir(parents=True, exist_ok=True) + self.download_tmp.mkdir(parents=True, exist_ok=True) + + def __str__(self): + return str(self.__dict__) + + +CONFIG = Cfg() +# print(CONFIG) diff --git a/src_mac/crack.py b/src_mac/crack.py new file mode 100755 index 0000000..c46167b --- /dev/null +++ b/src_mac/crack.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +from subprocess import Popen +from time import sleep +import os + +from cfg import CONFIG, Log +from move_em import moveEmAll +from server import WinServer + + +print('Start cracking ...') +while True: + file = next(CONFIG.sync_out.glob('*.ipa'), None) + + if not file: + print('Nothing to do. Retry in 10s ...') + sleep(10) + continue + + Log.info('[install] %s ...', file.name) + WinServer.install(file) + + Log.info('[crack] %s ...', file.name) + shell = Popen(CONFIG.ssh_cmd_crack, shell=True) + if shell.wait() != 0: + raise RuntimeError('Error during cracking command') + + Log.info('[pull] %s ...', file.name) + shell = Popen(CONFIG.ssh_cmd_sync, shell=True) + if shell.wait() != 0: + raise RuntimeError('Error during sync-download') + + Log.info('[delete] %s', file.name) + os.remove(file) # file on sync_out dir + + moveEmAll() diff --git a/src_mac/download.py b/src_mac/download.py new file mode 100755 index 0000000..9e6a346 --- /dev/null +++ b/src_mac/download.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +from cfg import CONFIG, Log +from lib import downloadAllUntil, enumAppIds +from repack_ipa import repackIpa + + +# findLatestVersion(000, CONFIG.max_os) +# downloadSpecificVersion(000, 000) +# exit(0) + +appIds = list(enumAppIds()) +# appIds = [000] + +for i, appId in enumerate(appIds): + Log.info('Checking [%d/%d] %s', i + 1, len(appIds), appId) + for i in range(150): + path = downloadAllUntil(i, appId, CONFIG.max_os, rmIncompatible=True) + if path: + repackIpa(path) + +print('done.') diff --git a/src_mac/extract_versions.py b/src_mac/extract_versions.py new file mode 100755 index 0000000..e451e07 --- /dev/null +++ b/src_mac/extract_versions.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +from argparse import ArgumentParser +import shutil + +from cfg import CONFIG +from lib import downloadPath, updateVersionMap, versionToInt + + +if __name__ == '__main__': + cli = ArgumentParser() + cli.add_argument('ipa', nargs='+') + cli.add_argument('-m', '--move', action='store_true') + args = cli.parse_args() + max_os = versionToInt(CONFIG.max_os) + + for fname in args.ipa: + info = updateVersionMap(fname) + if args.move and versionToInt(info.osVer) <= max_os: + download_path = downloadPath(info.appId, info.verId) + shutil.move(fname, download_path) diff --git a/src_mac/ipatool-py/.gitignore b/src_mac/ipatool-py/.gitignore new file mode 100755 index 0000000..f46337f --- /dev/null +++ b/src_mac/ipatool-py/.gitignore @@ -0,0 +1,4 @@ +.idea +__pycache__ +venv/ +downloaded/ \ No newline at end of file diff --git a/src_mac/ipatool-py/README.md b/src_mac/ipatool-py/README.md new file mode 100755 index 0000000..83f5a49 --- /dev/null +++ b/src_mac/ipatool-py/README.md @@ -0,0 +1,112 @@ +# IPATool-py + +Python version of IPATool! + +**Now Supports**: + - **Purchasing App via `--purchase`** + - **Downloading Old IPA via iTunes Server** + +## Installation + +``` +pip3 install -r requirements.txt +``` + +## Usage + +There're three commands: lookup, historyver, download. Each command's usage can be found by `-h` option. + +You can also chain multiple command, last command's output will be passed to next command (so you don't need to supply some arguments like appVerId) + +### Download Newest Version + +Download an app using bundleID (-o can be omited) +``` +python3 main.py lookup -b com.touchingapp.potatsolite -c JP download -e APPLE_EMAIL -p APPLE_PWD -o DIR +``` + +Or appID (`XXXXX` in the `apps.apple.com/app/xxxx/idXXXXXX`) +``` +python3 main.py download -i XXXXX +``` + +You can also purchase apps when downloading using `--purchase`: +``` +python3 main.py lookup -b com.touchingapp.potatsolite -c JP download --purchase -e APPLE_EMAIL -p APPLE_PWD -o DIR +``` + +### Download OLD Version + +Old versions must be downloaded together with `iTunes Server`. You can get `iTunes Server` in several ways: +- Using [action-ipadown](https://github.com/NyaMisty/action-ipadown) directly, which integrated this tool + - NOTE: this method does not support 2FA +- Manually way with Windows: (supports 2FA) + - download this repo: https://github.com/NyaMisty/actions-iTunes-header + - install iTunes 12.6.5.3, from https://secure-appldnld.apple.com/itunes12/091-87819-20180912-69177170-B085-11E8-B6AB-C1D03409AD2A6/iTunes64Setup.exe + - patch the iTunes using `actions-iTunes-header/workflow_helper/iTunesInstall/patch_itunes.py` + - install frida: `pip3 install frida` + - open iTunes, sign out & re-login your account + - run: `actions-iTunes-header/workflow_helper/iTunesDownload/get_header.py` +- Manually way with jailbroken iOS device: (supports 2FA) + - download [KbsyncTool](https://github.com/Lessica/KbsyncTool/releases) + - install `com.darwindev.kbsync_XXX.deb` on your jailbroken device + - exec `kbsynctool -s 9000` on your jailbroken device + - you will find log `Using -s http://192.168.100.227:9000/...`, use it as server address in next step + +After setting up the server, you can run this tool to download a specific version +``` +python3 main.py lookup -b com.touchingapp.potatsolite -c JP download -s http://127.0.0.1:9000 --appVerId 833889087 +``` + +NOTE: Some users are reporting that you need to **authorize computer** and make first purchase in iTunes with marked "do not ask for password" before using the iTunes server. (See #26) + +### Get History Ver (usually used together with JSON) + +Get all appVerId of app from Apple +``` +python3 main.py lookup -b com.touchingapp.potatsolite -c JP historyver -e APPLE_EMAIL -p APPLE_PWD +``` + +### Lookup (usually used together with JSON) + +Query app basic information: +- By bundleID: `python3 main.py lookup -b com.touchingapp.potatsolite -c JP` +- By appID: `python3 main.py lookup -i 1239860606 -c JP` + +Query appVerId: +``` +python3 main.py lookup -b com.touchingapp.potatsolite -c JP --get-verid +``` + +### Headless Usage + +For each command you can use `--json` switch to get result of command in JSON + +``` +python3 main.py --json lookup -b com.touchingapp.potatsolite -c JP --get-verid +python3 main.py --json lookup -b com.touchingapp.potatsolite -c JP historyver -e APPLE_EMAIL -p APPLE_PWD +``` + +### For Large Scale Scraping + +You can download all versions of an app like this: +``` +python3 main.py --json download --itunes-server http://XXX.XXX.XXX.XXX:9000 --appId 414478124 --purchase --downloadAllVersion +``` + +- In this mode, errors will only be logged instead of interrupting the whole process +- For each downloaded app version, it will output a line of json in stdout like this: + ``` + {"appName": "WeChat", "appBundleId": "com.tencent.xin", "appVer": "6.5.13.34", "appId": 414478124, "appVerId": 822899148, "downloadedIPA": "wechat\\com.tencent.xin-6.5.13.34-414478124-822899148.ipa", "downloadedVerId": 822899148} + ``` + Logs will only be printed to stderr, so you can parse this line for automation. + + +## Development + +- All requests' reqBody and respBody are modeled using modified JSONSchema2PoPo2 (see my NyaMisty/JSONSchema2PoPo2), you can regenerate the binding by cd into `reqs/schemas` and execute `python3 -m schema_defs` +- See more information on how to generate schema in reqs/schemas directory + +## Credit + +- Thanks @majd's ipatool, which is written in swift diff --git a/src_mac/ipatool-py/main.py b/src_mac/ipatool-py/main.py new file mode 100755 index 0000000..0817dbe --- /dev/null +++ b/src_mac/ipatool-py/main.py @@ -0,0 +1,567 @@ +#!/usr/bin/python3 +import os +import pickle +import sys +import time +import zipfile + +from requests.adapters import HTTPAdapter +from urllib3 import Retry + +from reqs.itunes import * +from reqs.store import * +import reprlib + +reprlib.aRepr.maxstring = 200 + +import argparse + +import logging +from rich.logging import RichHandler +from rich.console import Console +import rich + +rich.get_console().file = sys.stderr +if rich.get_console().width < 100: + rich.get_console().width = 100 + +logging_handler = RichHandler(rich_tracebacks=True) +logging.basicConfig( + level="INFO", + format="%(message)s", + datefmt="[%X]", + handlers=[logging_handler] +) +logging.getLogger('urllib3').setLevel(logging.WARNING) +retryLogger = logging.getLogger('urllib3.util.retry') +retryLogger.setLevel(logging.DEBUG) +retryLogger.handlers = [logging_handler] +retryLogger.propagate = False + +logger = logging.getLogger('main') + +import requests + +def get_zipinfo_datetime(timestamp=None): + # Some applications need reproducible .whl files, but they can't do this without forcing + # the timestamp of the individual ZipInfo objects. See issue #143. + timestamp = int(timestamp or time.time()) + return time.gmtime(timestamp)[0:6] + +def downloadFile(url, outfile, retries=10): + for retry in range(retries): + try: + _downloadFile(url, outfile) + break + except Exception as e: + logger.info("Error during downloading %s (retry %d/%d), error %s", url, retry, retries, e) + os.remove(outfile) + logger.info("Download success in retry %d", retry) + +download_sess = requests.Session() +download_sess.headers = {"User-Agent": CONFIGURATOR_UA} +DOWNLOAD_READ_TIMEOUT = 25.0 +def _downloadFile(url, outfile): + with download_sess.get(url, stream=True, timeout=DOWNLOAD_READ_TIMEOUT) as r: + if not r.headers.get('Content-Length'): + raise Exception("server is not returning Content-Length!") + totalLen = int(r.headers.get('Content-Length', '0')) + downLen = 0 + r.raise_for_status() + try: + with open(outfile, 'wb') as f: + lastLen = 0 + for chunk in r.iter_content(chunk_size=1 * 1024 * 1024): + # If you have chunk encoded response uncomment if + # and set chunk_size parameter to None. + # if chunk: + f.write(chunk) + downLen += len(chunk) + if totalLen and downLen - lastLen > totalLen * 0.05: + logger.info("Download progress: %3.2f%% (%5.1fM /%5.1fM)" % ( + downLen / totalLen * 100, downLen / 1024 / 1024, totalLen / 1024 / 1024)) + lastLen = downLen + finally: + if downLen != totalLen: # ensure no partial downloaded files exists + os.unlink(outfile) + if downLen != totalLen: + raise Exception("failed to completely download the IPA file") + + return outfile + +class IPATool(object): + def __init__(self): + self.sess = requests.Session() + + retry_strategy = Retry( + connect=4, + read=4, + # total=8, + status=20, + allowed_methods=None, + status_forcelist=[429, 502, 503], + backoff_factor=1.0, + respect_retry_after_header=False, + ) + self.sess.mount("https://", HTTPAdapter(max_retries=retry_strategy)) + self.sess.mount("http://", HTTPAdapter(max_retries=retry_strategy)) + IPATOOL_PROXY = os.getenv("IPATOOL_PROXY") + if IPATOOL_PROXY is not None: + self.sess.proxies.update( + {'http': IPATOOL_PROXY, 'https': IPATOOL_PROXY}) + # self.sess.headers = {} + self.sess.headers = {"Connection": "close"} + self.sess.keep_alive = False + + self.appId = None + # self.appInfo = None + self.appVerId = None + self.appVerIds = None + + self.jsonOut = None + + def tool_main(self): + commparser = argparse.ArgumentParser(description='IPATool-Python Commands.', add_help=False) + subp = commparser.add_subparsers(dest='command', required=True) + lookup_p = subp.add_parser('lookup') + id_group = lookup_p.add_mutually_exclusive_group(required=True) + id_group.add_argument('--bundle-id', '-b', dest='bundle_id') + id_group.add_argument('--appId', '-i', dest='appId') + lookup_p.add_argument('--country', '-c', dest='country', required=True) + lookup_p.add_argument('--get-verid', dest='get_verid', action='store_true') + lookup_p.set_defaults(func=self.handleLookup) + + def add_auth_options(p): + auth_p = p.add_argument_group('Auth Options', 'Must specify either Apple ID & Password, or iTunes Server URL') + appleid = auth_p.add_argument('--appleid', '-e') + passwd = auth_p.add_argument('--password', '-p') + sessdir = auth_p.add_argument('--session-dir', dest='session_dir', default=None) + + itunessrv = auth_p.add_argument('--itunes-server', '-s', dest='itunes_server') + + ## Multiple hack here just to achieve (appleid & password) || itunes_server + # p._optionals.conflict_handler = 'ignore' + # p._optionals._handle_conflict_ignore = lambda *args: None + auth_p = p.add_mutually_exclusive_group(required=True) + auth_p._group_actions.append(appleid) + auth_p._group_actions.append(itunessrv) + # auth_p._group_actions.append(sessdir) + + auth_p = p.add_mutually_exclusive_group(required=True) + auth_p._group_actions.append(passwd) + auth_p._group_actions.append(itunessrv) + + purchase_p = subp.add_parser('purchase') + add_auth_options(purchase_p) + purchase_p.add_argument('--appId', '-i', dest='appId') + purchase_p.set_defaults(func=self.handlePurchase) + + down_p = subp.add_parser('download') + add_auth_options(down_p) + down_p.add_argument('--appId', '-i', dest='appId') + down_p.add_argument('--appVerId', dest='appVerId') + down_p.add_argument('--purchase', action='store_true') + down_p.add_argument('--downloadAllVersion', action='store_true') + down_p.add_argument('--output-dir', '-o', dest='output_dir', default='.') + down_p.set_defaults(func=self.handleDownload) + + his_p = subp.add_parser('historyver') + his_p.add_argument('--appId', '-i', dest='appId') + his_p.add_argument('--purchase', action='store_true') + his_p.add_argument('--output-dir', '-o', dest='output_dir', default='.') + add_auth_options(his_p) + his_p.set_defaults(func=self.handleHistoryVersion) + + parser = argparse.ArgumentParser(description='IPATool-Python.', parents=[commparser]) + parser.add_argument('--log-level', '-l', dest='log_level', default='info', + help='output level (default: info)') + parser.add_argument('--json', dest='out_json', action='store_true', + help='output json in stdout (log will always be put into stderr)') + + # parse global flags & first comm's arguments + args, rest = parser.parse_known_args() + logging.getLogger().setLevel(args.log_level.upper()) + outJson = args.out_json + + while True: + args.func(args) + if not rest: + break + args, rest = commparser.parse_known_args(rest) + + if outJson and self.jsonOut: + print(json.dumps(self.jsonOut, ensure_ascii=False)) + + def _outputJson(self, obj): + self.jsonOut = obj + + def handleLookup(self, args): + if args.bundle_id: + s = 'BundleID %s' % args.bundle_id + else: + s = 'AppID %s' % args.appId + logger.info('Looking up app in country %s with BundleID %s' % (args.country, s)) + iTunes = iTunesClient(self.sess) + appInfos = iTunes.lookup(bundleId=args.bundle_id, appId=args.appId, country=args.country) + if appInfos.resultCount != 1: + logger.fatal("Failed to find app in country %s with %s" % (args.country, s)) + return + appInfo = appInfos.results[0] + logger.info("Found app:\n\tName: %s\n\tVersion: %s\n\tbundleId: %s\n\tappId: %s" % (appInfo.trackName, appInfo.version, appInfo.bundleId, appInfo.trackId)) + self.appId = appInfo.trackId + # self.appInfo = appInfo + + ret = { + "name": appInfo.trackName, + "version": appInfo.version, + "appId": appInfo.trackId, + "bundleId": appInfo.bundleId, + } + + if args.get_verid: + logger.info("Retrieving verId using iTunes webpage...") + verId = iTunes.getAppVerId(self.appId, args.country) + logger.info("Got current verId using iTunes webpage: %s" % verId) + ret["appVerId"] = verId + + self._outputJson(ret) + + storeClientCache = {} + def _get_StoreClient(self, args): + cachekey = args.itunes_server or args.appleid + store, lastseen = self.storeClientCache.get(cachekey, (None, None,)) + if store: + if time.time() - lastseen < 30.0: + return store + del self.storeClientCache[cachekey] + + newSess = pickle.loads(pickle.dumps(self.sess)) + Store = StoreClient(newSess) + + if args.itunes_server: + logger.info("Using iTunes interface %s to download app!" % args.itunes_server) + servUrl = args.itunes_server + def handle_iTunes_provider(url): + startTime = time.time() + r = requests.get(servUrl, params={ + 'url': url + }) + logger.debug("got itunes header in %.2f seconds", time.time() - startTime) + + ret = r.json() + kbsync = bytes.fromhex(ret.pop('kbsync')) + guid = ret.pop('guid') + retHdrs = ret.pop('headers') + handled = { + 'headers': retHdrs, + 'kbsync': kbsync, + 'guid': guid, + } + if 'sbsync' in ret: + handled['sbsync'] = bytes.fromhex(ret.pop('sbsync')) + if 'afds' in ret: + handled['afds'] = ret.pop('afds') + return handled + Store.iTunes_provider = handle_iTunes_provider + else: + appleid = args.appleid + applepass = args.password + + needLogin = True + session_cache = os.path.join(args.session_dir, args.appleid) if args.session_dir else None + if session_cache and os.path.exists(session_cache): + needLogin = False + try: + # inside try in case the file format changed + with open(session_cache, "r") as f: + content = f.read() + Store.authenticate_load_session(content) + except Exception as e: + logger.warning(f"Error loading session {session_cache}") + os.unlink(session_cache) + needLogin = True + else: + logger.info('Loaded session for %s' % (str(Store.authInfo))) + if needLogin: + logger.info("Logging into iTunes as %s ..." % appleid) + + Store.authenticate(appleid, applepass) + logger.info('Logged in as %s' % (str(Store.authInfo))) + + if session_cache: + with open(session_cache, "w") as f: + f.write(Store.authenticate_save_session()) + + def authedPost(*args, **kwargs): + if 'MZFinance.woa/wa/authenticate' in args[0]: + return Store.sess.original_post(*args, **kwargs) + for i in range(3): + r = Store.sess.original_post(*args, **kwargs) + isAuthFail = False + try: + d = plistlib.loads(r.content) + if str(d['failureType']) in ("2034", "1008"): + isAuthFail = True + except: + return r + if not isAuthFail: + return r + Store.authenticate(appleid, applepass) + if session_cache: + with open(session_cache, "w") as f: + f.write(Store.authenticate_save_session()) + continue + Store.sess.original_post = Store.sess.post + Store.sess.post = authedPost + + self.storeClientCache[cachekey] = (Store, time.time(),) + return Store + + def _handleStoreException(self, _e): + e = _e # type: StoreException + logger.fatal("Store %s failed! Message: %s%s" % (e.req, e.errMsg, " (errorType %s)" % e.errType if e.errType else '')) + logger.fatal(" Raw Response: %s" % (e.resp)) + + def handlePurchase(self, args): + Store = self._get_StoreClient(args) + logger.info('Try to purchase appId %s' % (self.appId)) + try: + Store.purchase(self.appId) + except StoreException as e: + if e.errMsg == 'purchased_before': + logger.warning('You have already purchased appId %s before' % (self.appId)) + else: + raise + + def handleHistoryVersion(self, args, caches=True): + if args.appId: + self.appId = args.appId + + if not self.appId: + logger.fatal("appId not supplied!") + return + + versionsJsonPath = args.output_dir + f"/historyver_{self.appId}.json" + if caches: + if os.path.exists(versionsJsonPath): + cacheContent = None + try: + with open(versionsJsonPath) as f: + cacheContent = json.load(f) + except: + pass + if cacheContent is not None: + logger.info('Loaded history version cache for appId %s' % self.appId) + self.appVerIds = cacheContent['appVerIds'] + return + + logger.info('Retrieving history version for appId %s' % self.appId) + + try: + Store = self._get_StoreClient(args) + + logger.info('Retrieving download info for appId %s' % (self.appId)) + if args.purchase: + logger.info('Purchasing appId %s' % (self.appId)) + # We have already successfully purchased, so don't purchase again :) + self.handlePurchase(args) + args.purchase = False + + downResp = Store.download(self.appId, '', isRedownload=not args.purchase) + logger.debug('Got download info: %s', downResp) + if args.purchase: + # We have already successfully purchased, so don't purchase again :) + args.purchase = False + + if not downResp.songList: + logger.fatal("failed to get app download info!") + raise StoreException('download', downResp, 'no songList') + downInfo = downResp.songList[0] + logger.info('Got available version ids %s', downInfo.metadata.softwareVersionExternalIdentifiers) + self._outputJson({ + "appVerIds": downInfo.metadata.softwareVersionExternalIdentifiers + }) + self.appVerIds = downInfo.metadata.softwareVersionExternalIdentifiers + if caches: + with open(versionsJsonPath, 'w') as f: + json.dump({ + 'appVerIds': self.appVerIds, + }, f) + except StoreException as e: + self._handleStoreException(e) + if not e.errMsg.startswith('http error status') and not e.errMsg.startswith( + 'We are temporarily unable to process your request') and not e.errMsg.startswith( + "License not found"): + # this error is persistent (e.g. app deleted) + self.appVerIds = [] + if caches: + with open(versionsJsonPath, 'w') as f: + json.dump({ + 'appVerIds': self.appVerIds, + 'error': str(e), + 'errorResp': str(e.resp), + }, f) + + def handleDownload(self, args): + os.makedirs(args.output_dir, exist_ok=True) + if args.downloadAllVersion: + if os.path.exists(args.output_dir + "/all_done"): + logger.info('Already fully finished, skipping!') + return + self.handleHistoryVersion(args, caches=True) + if not self.appVerIds: + logger.fatal('failed to retrive history versions for appId %s', args.appId) + return + everything_succ = True + for appVerId in self.appVerIds: + self.jsonOut = None + stateFile = args.output_dir + '/' + str(appVerId) + '.finish' + if os.path.exists(stateFile): + logger.info('Skipping already downloaded') + continue + try: + self.appVerId = appVerId + self.downloadOne(args) + if args.out_json and self.jsonOut: + print(json.dumps(self.jsonOut, ensure_ascii=False)) + if self.jsonOut is not None: # successfully finished + with open(stateFile, 'w') as f: + f.write('1') + except Exception as e: + logger.fatal("error during downloading appVerId %s", appVerId, exc_info=1) + everything_succ = False + finally: + self.jsonOut = None + if everything_succ: + with open(args.output_dir + "/all_done", 'w') as f: + f.write("1") + else: + self.downloadOne(args) + + def downloadOne(self, args): + if args.appId: + self.appId = args.appId + if args.appVerId: + self.appVerId = args.appVerId + + if not self.appId: + logger.fatal("appId not supplied!") + return + + logger.info("Downloading appId %s appVerId %s", self.appId, self.appVerId) + try: + appleid = args.appleid + Store = self._get_StoreClient(args) + + if args.purchase: + self.handlePurchase(args) + + logger.info('Retrieving download info for appId %s%s' % (self.appId, " with versionId %s" % self.appVerId if self.appVerId else "")) + + downResp = Store.download(self.appId, self.appVerId, isRedownload=not args.purchase) + logger.debug('Got download info: %s', downResp.as_dict()) + + if not downResp.songList: + logger.fatal("failed to get app download info!") + raise StoreException('download', downResp, 'no songList') + downInfo = downResp.songList[0] + + appName = downInfo.metadata.bundleDisplayName + appId = downInfo.songId + appBundleId = downInfo.metadata.softwareVersionBundleId + appVerId = downInfo.metadata.softwareVersionExternalIdentifier + # when downloading history versions, bundleShortVersionString will always give a wrong version number (the newest one) + # should use bundleVersion in these cases + appVer = downInfo.metadata.bundleShortVersionString if not self.appVerId else downInfo.metadata.bundleVersion + + logger.info(f'Downloading app {appName} ({appBundleId}) with appId {appId} (version {appVer}, versionId {appVerId})') + + # if self.appInfo: + filename = '%s-%s-%s-%s.ipa' % (appBundleId, + appVer, + appId, + appVerId) + # else: + # filename = '%s-%s.ipa' % (self.appId, appVerId) + + filepath = os.path.join(args.output_dir, filename) + logger.info("Downloading ipa to %s" % filepath) + downloadFile(downInfo.URL, filepath) + metadata = downInfo.metadata.as_dict() + if appleid: + metadata["apple-id"] = appleid + metadata["userName"] = appleid + logger.info("Writing out iTunesMetadata.plist...") + if zipfile.is_zipfile(filepath): + with zipfile.ZipFile(filepath, 'a') as ipaFile: + logger.debug("Writing iTunesMetadata.plist") + ipaFile.writestr(zipfile.ZipInfo("iTunesMetadata.plist", get_zipinfo_datetime()), plistlib.dumps(metadata)) + logger.debug("Writing IPAToolInfo.plist") + ipaFile.writestr(zipfile.ZipInfo("IPAToolInfo.plist", get_zipinfo_datetime()), plistlib.dumps(downResp.as_dict())) + + def findAppContentPath(c): + if not c.startswith('Payload/'): + return False + pathparts = c.strip('/').split('/') + if len(pathparts) != 2: + return False + if not pathparts[1].endswith(".app"): + return False + return True + appContentDirChoices = [c for c in ipaFile.namelist() if findAppContentPath(c)] + if len(appContentDirChoices) != 1: + raise Exception("failed to find appContentDir, choices %s", appContentDirChoices) + appContentDir = appContentDirChoices[0].rstrip('/') + + processedSinf = False + if (appContentDir + '/SC_Info/Manifest.plist') in ipaFile.namelist(): + #Try to get the Manifest.plist file, since it doesn't always exist. + scManifestData = ipaFile.read(appContentDir + '/SC_Info/Manifest.plist') + logger.debug("Got SC_Info/Manifest.plist: %s", scManifestData) + scManifest = plistlib.loads(scManifestData) + sinfs = {c.id: c.sinf for c in downInfo.sinfs} + if 'SinfPaths' in scManifest: + for i, sinfPath in enumerate(scManifest['SinfPaths']): + logger.debug("Writing sinf to %s", sinfPath) + ipaFile.writestr(appContentDir + '/' + sinfPath, sinfs[i]) + processedSinf = True + if not processedSinf: + logger.info('Manifest.plist does not exist! Assuming it is an old app without one...') + infoListData = ipaFile.read(appContentDir + '/Info.plist') #Is this not loaded anywhere yet? + infoList = plistlib.loads(infoListData) + sinfPath = appContentDir + '/SC_Info/'+infoList['CFBundleExecutable']+".sinf" + logger.debug("Writing sinf to %s", sinfPath) + #Assuming there is only one .sinf file, hence the 0 + ipaFile.writestr(sinfPath, downInfo.sinfs[0].sinf) + processedSinf = True + + logger.info("Downloaded ipa to %s" % filename) + else: + plist = filepath[:-4]+".info.plist" + with open(plist, "wb") as f: + f.write(plistlib.dumps(downResp.as_dict())) + plist = filepath[:-4]+".plist" + with open(plist, "wb") as f: + f.write(plistlib.dumps(metadata)) + logger.info("Downloaded ipa to %s and plist to %s" % (filename, plist)) + + self._outputJson({ + "appName": appName, + "appBundleId": appBundleId, + "appVer": appVer, + "appId": appId, + "appVerId": appVerId, + + "downloadedIPA": filepath, + "downloadedVerId": appVerId, + "downloadURL": downInfo.URL, + }) + except StoreException as e: + self._handleStoreException(e) + +def main(): + tool = IPATool() + tool.tool_main() + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/src_mac/ipatool-py/reqs/__init__.py b/src_mac/ipatool-py/reqs/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/src_mac/ipatool-py/reqs/itunes.py b/src_mac/ipatool-py/reqs/itunes.py new file mode 100755 index 0000000..e91223d --- /dev/null +++ b/src_mac/ipatool-py/reqs/itunes.py @@ -0,0 +1,47 @@ +__all__ = ['iTunesClient'] + +import json +import re + +from reqs.schemas.itunes_lookup_resp import ItunesLookupResp +import requests + +STORE_TABLE = {"AE":"143481-2,32","AG":"143540-2,32","AI":"143538-2,32","AL":"143575-2,32","AM":"143524-2,32","AO":"143564-2,32","AR":"143505-28,32","AT":"143445-4,32","AU":"143460-27,32","AZ":"143568-2,32","BB":"143541-2,32","BE":"143446-2,32","BF":"143578-2,32","BG":"143526-2,32","BH":"143559-2,32","BJ":"143576-2,32","BM":"143542-2,32","BN":"143560-2,32","BO":"143556-28,32","BR":"143503-15,32","BS":"143539-2,32","BT":"143577-2,32","BW":"143525-2,32","BY":"143565-2,32","BZ":"143555-2,32","CA":"143455-6,32","CG":"143582-2,32","CH":"143459-57,32","CL":"143483-28,32","CN":"143465-19,32","CO":"143501-28,32","CR":"143495-28,32","CV":"143580-2,32","CY":"143557-2,32","CZ":"143489-2,32","DE":"143443-4,32","DK":"143458-2,32","DM":"143545-2,32","DO":"143508-28,32","DZ":"143563-2,32","EC":"143509-28,32","EE":"143518-2,32","EG":"143516-2,32","ES":"143454-8,32","FI":"143447-2,32","FJ":"143583-2,32","FM":"143591-2,32","FR":"143442-3,32","GB":"143444-2,32","GD":"143546-2,32","GH":"143573-2,32","GM":"143584-2,32","GR":"143448-2,32","GT":"143504-28,32","GW":"143585-2,32","GY":"143553-2,32","HK":"143463-45,32","HN":"143510-28,32","HR":"143494-2,32","HU":"143482-2,32","ID":"143476-2,32","IE":"143449-2,32","IL":"143491-2,32","IN":"143467-2,32","IS":"143558-2,32","IT":"143450-7,32","JM":"143511-2,32","JO":"143528-2,32","JP":"143462-9,32","KE":"143529-2,32","KG":"143586-2,32","KH":"143579-2,32","KN":"143548-2,32","KR":"143466-13,32","KW":"143493-2,32","KY":"143544-2,32","KZ":"143517-2,32","LA":"143587-2,32","LB":"143497-2,32","LC":"143549-2,32","LK":"143486-2,32","LR":"143588-2,32","LT":"143520-2,32","LU":"143451-2,32","LV":"143519-2,32","MD":"143523-2,32","MG":"143531-2,32","MK":"143530-2,32","ML":"143532-2,32","MN":"143592-2,32","MO":"143515-45,32","MR":"143590-2,32","MS":"143547-2,32","MT":"143521-2,32","MU":"143533-2,32","MW":"143589-2,32","MX":"143468-28,32","MY":"143473-2,32","MZ":"143593-2,32","NA":"143594-2,32","NE":"143534-2,32","NG":"143561-2,32","NI":"143512-28,32","NL":"143452-10,32","NO":"143457-2,32","NP":"143484-2,32","NZ":"143461-27,32","OM":"143562-2,32","PA":"143485-28,32","PE":"143507-28,32","PG":"143597-2,32","PH":"143474-2,32","PK":"143477-2,32","PL":"143478-2,32","PT":"143453-24,32","PW":"143595-2,32","PY":"143513-28,32","QA":"143498-2,32","RO":"143487-2,32","RU":"143469-16,32","SA":"143479-2,32","SB":"143601-2,32","SC":"143599-2,32","SE":"143456-17,32","SG":"143464-19,32","SI":"143499-2,32","SK":"143496-2,32","SL":"143600-2,32","SN":"143535-2,32","SR":"143554-2,32","ST":"143598-2,32","SV":"143506-28,32","SZ":"143602-2,32","TC":"143552-2,32","TD":"143581-2,32","TH":"143475-2,32","TJ":"143603-2,32","TM":"143604-2,32","TN":"143536-2,32","TR":"143480-2,32","TT":"143551-2,32","TW":"143470-18,32","TZ":"143572-2,32","UA":"143492-2,32","UG":"143537-2,32","US":"143441-1,32","UY":"143514-2,32","UZ":"143566-2,32","VC":"143550-2,32","VE":"143502-28,32","VG":"143543-2,32","VN":"143471-2,32","YE":"143571-2,32","ZA":"143472-2,32","ZW":"143605-2,32"} + + +class iTunesClient(object): + def __init__(self, sess: requests.Session): + self.sess = sess + + # curl -k -X GET \ + # -H "Content-Type: application/x-www-form-urlencoded" \ + # https://itunes.apple.com/lookup?bundleId=com.touchingapp.potatsolite&limit=1&media=software + def lookup(self, bundleId=None, appId=None, term=None, country="US", limit=1, media="software") -> ItunesLookupResp: + r = self.sess.get("https://itunes.apple.com/lookup?", + params={ + "bundleId": bundleId, + "id": appId, + "term": term, + "country": country, + "limit": limit, + "media": media, + }, + headers={ + "Content-Type": "application/x-www-form-urlencoded", + }) + return ItunesLookupResp.from_dict(r.json()) + + def getAppVerId(self, appId, country): + if not ',' in country: + storeFront = STORE_TABLE[country.upper()] + else: + storeFront = country + appInfo = requests.get("https://apps.apple.com/app/id%s" % appId, headers={"X-Apple-Store-Front": storeFront}).text + try: + appParam = re.findall(r'"buyParams":"(.*?)"', appInfo)[0] + except: + appParam = re.findall(r'buy-params="(.*?)"', appInfo)[0] + appParam = appParam.replace('&', '&') + appParamDict = dict((c.split('=') for c in json.loads('"%s"' % appParam).split('&'))) + appVer = appParamDict['appExtVrsId'] + return appVer \ No newline at end of file diff --git a/src_mac/ipatool-py/reqs/schemas/README.md b/src_mac/ipatool-py/reqs/schemas/README.md new file mode 100755 index 0000000..454c807 --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/README.md @@ -0,0 +1,18 @@ +# Schema Definitions for ipatool-py + +In this directory, JSON Schema Definition files are stored in `schema_defs`, with corresponding plist examples in `schema_examples` + +## How to generate schema from plist + +1. Convert plist to corresponding JSON, using either `plistlib` or online tools +2. Use https://www.liquid-technologies.com/online-json-to-schema-converter to convert JSON to schema + - You have to switch the `Array Rules` option to `List Validation` +3. Merge different request / response body's schema manually + - Usually the "required" field can help you merging the json schema + +## Regenerate schema bindings + +Run this in current folder: +``` +python3 -m schema_defs +``` \ No newline at end of file diff --git a/src_mac/ipatool-py/reqs/schemas/__init__.py b/src_mac/ipatool-py/reqs/schemas/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/src_mac/ipatool-py/reqs/schemas/itunes_lookup_resp.py b/src_mac/ipatool-py/reqs/schemas/itunes_lookup_resp.py new file mode 100755 index 0000000..cb7a391 --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/itunes_lookup_resp.py @@ -0,0 +1,1593 @@ +from reprlib import repr as limitedRepr + + +from typing import List + + +class ItunesLookupResp: + class _results: + + _types_map = { + "appletvScreenshotUrls": {"type": list, "subtype": float}, + "screenshotUrls": {"type": list, "subtype": str}, + "ipadScreenshotUrls": {"type": list, "subtype": str}, + "artworkUrl60": {"type": str, "subtype": None}, + "artworkUrl512": {"type": str, "subtype": None}, + "artworkUrl100": {"type": str, "subtype": None}, + "artistViewUrl": {"type": str, "subtype": None}, + "supportedDevices": {"type": list, "subtype": str}, + "advisories": {"type": list, "subtype": float}, + "isGameCenterEnabled": {"type": bool, "subtype": None}, + "kind": {"type": str, "subtype": None}, + "features": {"type": list, "subtype": str}, + "minimumOsVersion": {"type": str, "subtype": None}, + "trackCensoredName": {"type": str, "subtype": None}, + "languageCodesISO2A": {"type": list, "subtype": str}, + "fileSizeBytes": {"type": str, "subtype": None}, + "formattedPrice": {"type": str, "subtype": None}, + "contentAdvisoryRating": {"type": str, "subtype": None}, + "averageUserRatingForCurrentVersion": {"type": float, "subtype": None}, + "userRatingCountForCurrentVersion": {"type": int, "subtype": None}, + "averageUserRating": {"type": float, "subtype": None}, + "trackViewUrl": {"type": str, "subtype": None}, + "trackContentRating": {"type": str, "subtype": None}, + "releaseDate": {"type": str, "subtype": None}, + "genreIds": {"type": list, "subtype": str}, + "primaryGenreName": {"type": str, "subtype": None}, + "trackId": {"type": int, "subtype": None}, + "trackName": {"type": str, "subtype": None}, + "sellerName": {"type": str, "subtype": None}, + "isVppDeviceBasedLicensingEnabled": {"type": bool, "subtype": None}, + "currentVersionReleaseDate": {"type": str, "subtype": None}, + "releaseNotes": {"type": str, "subtype": None}, + "primaryGenreId": {"type": int, "subtype": None}, + "currency": {"type": str, "subtype": None}, + "version": {"type": str, "subtype": None}, + "wrapperType": {"type": str, "subtype": None}, + "artistId": {"type": int, "subtype": None}, + "artistName": {"type": str, "subtype": None}, + "genres": {"type": list, "subtype": str}, + "price": {"type": float, "subtype": None}, + "description": {"type": str, "subtype": None}, + "bundleId": {"type": str, "subtype": None}, + "userRatingCount": {"type": int, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "appletvScreenshotUrls": { + "required": True, + }, + "screenshotUrls": { + "required": True, + }, + "ipadScreenshotUrls": { + "required": True, + }, + "artworkUrl60": { + "required": True, + }, + "artworkUrl512": { + "required": True, + }, + "artworkUrl100": { + "required": True, + }, + "artistViewUrl": { + "required": True, + }, + "supportedDevices": { + "required": True, + }, + "advisories": { + "required": True, + }, + "isGameCenterEnabled": { + "required": True, + }, + "kind": { + "required": True, + }, + "features": { + "required": True, + }, + "minimumOsVersion": { + "required": True, + }, + "trackCensoredName": { + "required": True, + }, + "languageCodesISO2A": { + "required": True, + }, + "fileSizeBytes": { + "required": True, + }, + "formattedPrice": { + "required": True, + }, + "contentAdvisoryRating": { + "required": True, + }, + "averageUserRatingForCurrentVersion": { + "required": True, + }, + "userRatingCountForCurrentVersion": { + "required": True, + }, + "averageUserRating": { + "required": True, + }, + "trackViewUrl": { + "required": True, + }, + "trackContentRating": { + "required": True, + }, + "releaseDate": { + "required": True, + }, + "genreIds": { + "required": True, + }, + "primaryGenreName": { + "required": True, + }, + "trackId": { + "required": True, + }, + "trackName": { + "required": True, + }, + "sellerName": { + "required": True, + }, + "isVppDeviceBasedLicensingEnabled": { + "required": True, + }, + "currentVersionReleaseDate": { + "required": True, + }, + "releaseNotes": { + "required": True, + }, + "primaryGenreId": { + "required": True, + }, + "currency": { + "required": True, + }, + "version": { + "required": True, + }, + "wrapperType": { + "required": True, + }, + "artistId": { + "required": True, + }, + "artistName": { + "required": True, + }, + "genres": { + "required": True, + }, + "price": { + "required": True, + }, + "description": { + "required": True, + }, + "bundleId": { + "required": True, + }, + "userRatingCount": { + "required": True, + }, + } + + def __init__( + self, + appletvScreenshotUrls: List[float] = None, + screenshotUrls: List[str] = None, + ipadScreenshotUrls: List[str] = None, + artworkUrl60: str = None, + artworkUrl512: str = None, + artworkUrl100: str = None, + artistViewUrl: str = None, + supportedDevices: List[str] = None, + advisories: List[float] = None, + isGameCenterEnabled: bool = None, + kind: str = None, + features: List[str] = None, + minimumOsVersion: str = None, + trackCensoredName: str = None, + languageCodesISO2A: List[str] = None, + fileSizeBytes: str = None, + formattedPrice: str = None, + contentAdvisoryRating: str = None, + averageUserRatingForCurrentVersion: float = None, + userRatingCountForCurrentVersion: int = None, + averageUserRating: float = None, + trackViewUrl: str = None, + trackContentRating: str = None, + releaseDate: str = None, + genreIds: List[str] = None, + primaryGenreName: str = None, + trackId: int = None, + trackName: str = None, + sellerName: str = None, + isVppDeviceBasedLicensingEnabled: bool = None, + currentVersionReleaseDate: str = None, + releaseNotes: str = None, + primaryGenreId: int = None, + currency: str = None, + version: str = None, + wrapperType: str = None, + artistId: int = None, + artistName: str = None, + genres: List[str] = None, + price: float = None, + description: str = None, + bundleId: str = None, + userRatingCount: int = None, + ): + pass + self.__appletvScreenshotUrls = appletvScreenshotUrls + self.__screenshotUrls = screenshotUrls + self.__ipadScreenshotUrls = ipadScreenshotUrls + self.__artworkUrl60 = artworkUrl60 + self.__artworkUrl512 = artworkUrl512 + self.__artworkUrl100 = artworkUrl100 + self.__artistViewUrl = artistViewUrl + self.__supportedDevices = supportedDevices + self.__advisories = advisories + self.__isGameCenterEnabled = isGameCenterEnabled + self.__kind = kind + self.__features = features + self.__minimumOsVersion = minimumOsVersion + self.__trackCensoredName = trackCensoredName + self.__languageCodesISO2A = languageCodesISO2A + self.__fileSizeBytes = fileSizeBytes + self.__formattedPrice = formattedPrice + self.__contentAdvisoryRating = contentAdvisoryRating + self.__averageUserRatingForCurrentVersion = ( + averageUserRatingForCurrentVersion + ) + self.__userRatingCountForCurrentVersion = userRatingCountForCurrentVersion + self.__averageUserRating = averageUserRating + self.__trackViewUrl = trackViewUrl + self.__trackContentRating = trackContentRating + self.__releaseDate = releaseDate + self.__genreIds = genreIds + self.__primaryGenreName = primaryGenreName + self.__trackId = trackId + self.__trackName = trackName + self.__sellerName = sellerName + self.__isVppDeviceBasedLicensingEnabled = isVppDeviceBasedLicensingEnabled + self.__currentVersionReleaseDate = currentVersionReleaseDate + self.__releaseNotes = releaseNotes + self.__primaryGenreId = primaryGenreId + self.__currency = currency + self.__version = version + self.__wrapperType = wrapperType + self.__artistId = artistId + self.__artistName = artistName + self.__genres = genres + self.__price = price + self.__description = description + self.__bundleId = bundleId + self.__userRatingCount = userRatingCount + + def _get_appletvScreenshotUrls(self): + return self.__appletvScreenshotUrls + + def _set_appletvScreenshotUrls(self, value): + if not isinstance(value, list): + raise TypeError("appletvScreenshotUrls must be list") + if not all(isinstance(i, float) for i in value): + raise TypeError("appletvScreenshotUrls list values must be float") + + self.__appletvScreenshotUrls = value + + appletvScreenshotUrls = property( + _get_appletvScreenshotUrls, _set_appletvScreenshotUrls + ) + + def _get_screenshotUrls(self): + return self.__screenshotUrls + + def _set_screenshotUrls(self, value): + if not isinstance(value, list): + raise TypeError("screenshotUrls must be list") + if not all(isinstance(i, str) for i in value): + raise TypeError("screenshotUrls list values must be str") + + self.__screenshotUrls = value + + screenshotUrls = property(_get_screenshotUrls, _set_screenshotUrls) + + def _get_ipadScreenshotUrls(self): + return self.__ipadScreenshotUrls + + def _set_ipadScreenshotUrls(self, value): + if not isinstance(value, list): + raise TypeError("ipadScreenshotUrls must be list") + if not all(isinstance(i, str) for i in value): + raise TypeError("ipadScreenshotUrls list values must be str") + + self.__ipadScreenshotUrls = value + + ipadScreenshotUrls = property(_get_ipadScreenshotUrls, _set_ipadScreenshotUrls) + + def _get_artworkUrl60(self): + return self.__artworkUrl60 + + def _set_artworkUrl60(self, value): + if not isinstance(value, str): + raise TypeError("artworkUrl60 must be str") + + self.__artworkUrl60 = value + + artworkUrl60 = property(_get_artworkUrl60, _set_artworkUrl60) + + def _get_artworkUrl512(self): + return self.__artworkUrl512 + + def _set_artworkUrl512(self, value): + if not isinstance(value, str): + raise TypeError("artworkUrl512 must be str") + + self.__artworkUrl512 = value + + artworkUrl512 = property(_get_artworkUrl512, _set_artworkUrl512) + + def _get_artworkUrl100(self): + return self.__artworkUrl100 + + def _set_artworkUrl100(self, value): + if not isinstance(value, str): + raise TypeError("artworkUrl100 must be str") + + self.__artworkUrl100 = value + + artworkUrl100 = property(_get_artworkUrl100, _set_artworkUrl100) + + def _get_artistViewUrl(self): + return self.__artistViewUrl + + def _set_artistViewUrl(self, value): + if not isinstance(value, str): + raise TypeError("artistViewUrl must be str") + + self.__artistViewUrl = value + + artistViewUrl = property(_get_artistViewUrl, _set_artistViewUrl) + + def _get_supportedDevices(self): + return self.__supportedDevices + + def _set_supportedDevices(self, value): + if not isinstance(value, list): + raise TypeError("supportedDevices must be list") + if not all(isinstance(i, str) for i in value): + raise TypeError("supportedDevices list values must be str") + + self.__supportedDevices = value + + supportedDevices = property(_get_supportedDevices, _set_supportedDevices) + + def _get_advisories(self): + return self.__advisories + + def _set_advisories(self, value): + if not isinstance(value, list): + raise TypeError("advisories must be list") + if not all(isinstance(i, float) for i in value): + raise TypeError("advisories list values must be float") + + self.__advisories = value + + advisories = property(_get_advisories, _set_advisories) + + def _get_isGameCenterEnabled(self): + return self.__isGameCenterEnabled + + def _set_isGameCenterEnabled(self, value): + if not isinstance(value, bool): + raise TypeError("isGameCenterEnabled must be bool") + + self.__isGameCenterEnabled = value + + isGameCenterEnabled = property( + _get_isGameCenterEnabled, _set_isGameCenterEnabled + ) + + def _get_kind(self): + return self.__kind + + def _set_kind(self, value): + if not isinstance(value, str): + raise TypeError("kind must be str") + + self.__kind = value + + kind = property(_get_kind, _set_kind) + + def _get_features(self): + return self.__features + + def _set_features(self, value): + if not isinstance(value, list): + raise TypeError("features must be list") + if not all(isinstance(i, str) for i in value): + raise TypeError("features list values must be str") + + self.__features = value + + features = property(_get_features, _set_features) + + def _get_minimumOsVersion(self): + return self.__minimumOsVersion + + def _set_minimumOsVersion(self, value): + if not isinstance(value, str): + raise TypeError("minimumOsVersion must be str") + + self.__minimumOsVersion = value + + minimumOsVersion = property(_get_minimumOsVersion, _set_minimumOsVersion) + + def _get_trackCensoredName(self): + return self.__trackCensoredName + + def _set_trackCensoredName(self, value): + if not isinstance(value, str): + raise TypeError("trackCensoredName must be str") + + self.__trackCensoredName = value + + trackCensoredName = property(_get_trackCensoredName, _set_trackCensoredName) + + def _get_languageCodesISO2A(self): + return self.__languageCodesISO2A + + def _set_languageCodesISO2A(self, value): + if not isinstance(value, list): + raise TypeError("languageCodesISO2A must be list") + if not all(isinstance(i, str) for i in value): + raise TypeError("languageCodesISO2A list values must be str") + + self.__languageCodesISO2A = value + + languageCodesISO2A = property(_get_languageCodesISO2A, _set_languageCodesISO2A) + + def _get_fileSizeBytes(self): + return self.__fileSizeBytes + + def _set_fileSizeBytes(self, value): + if not isinstance(value, str): + raise TypeError("fileSizeBytes must be str") + + self.__fileSizeBytes = value + + fileSizeBytes = property(_get_fileSizeBytes, _set_fileSizeBytes) + + def _get_formattedPrice(self): + return self.__formattedPrice + + def _set_formattedPrice(self, value): + if not isinstance(value, str): + raise TypeError("formattedPrice must be str") + + self.__formattedPrice = value + + formattedPrice = property(_get_formattedPrice, _set_formattedPrice) + + def _get_contentAdvisoryRating(self): + return self.__contentAdvisoryRating + + def _set_contentAdvisoryRating(self, value): + if not isinstance(value, str): + raise TypeError("contentAdvisoryRating must be str") + + self.__contentAdvisoryRating = value + + contentAdvisoryRating = property( + _get_contentAdvisoryRating, _set_contentAdvisoryRating + ) + + def _get_averageUserRatingForCurrentVersion(self): + return self.__averageUserRatingForCurrentVersion + + def _set_averageUserRatingForCurrentVersion(self, value): + if not isinstance(value, float): + raise TypeError("averageUserRatingForCurrentVersion must be float") + + self.__averageUserRatingForCurrentVersion = value + + averageUserRatingForCurrentVersion = property( + _get_averageUserRatingForCurrentVersion, + _set_averageUserRatingForCurrentVersion, + ) + + def _get_userRatingCountForCurrentVersion(self): + return self.__userRatingCountForCurrentVersion + + def _set_userRatingCountForCurrentVersion(self, value): + if not isinstance(value, int): + raise TypeError("userRatingCountForCurrentVersion must be int") + + self.__userRatingCountForCurrentVersion = value + + userRatingCountForCurrentVersion = property( + _get_userRatingCountForCurrentVersion, _set_userRatingCountForCurrentVersion + ) + + def _get_averageUserRating(self): + return self.__averageUserRating + + def _set_averageUserRating(self, value): + if not isinstance(value, float): + raise TypeError("averageUserRating must be float") + + self.__averageUserRating = value + + averageUserRating = property(_get_averageUserRating, _set_averageUserRating) + + def _get_trackViewUrl(self): + return self.__trackViewUrl + + def _set_trackViewUrl(self, value): + if not isinstance(value, str): + raise TypeError("trackViewUrl must be str") + + self.__trackViewUrl = value + + trackViewUrl = property(_get_trackViewUrl, _set_trackViewUrl) + + def _get_trackContentRating(self): + return self.__trackContentRating + + def _set_trackContentRating(self, value): + if not isinstance(value, str): + raise TypeError("trackContentRating must be str") + + self.__trackContentRating = value + + trackContentRating = property(_get_trackContentRating, _set_trackContentRating) + + def _get_releaseDate(self): + return self.__releaseDate + + def _set_releaseDate(self, value): + if not isinstance(value, str): + raise TypeError("releaseDate must be str") + + self.__releaseDate = value + + releaseDate = property(_get_releaseDate, _set_releaseDate) + + def _get_genreIds(self): + return self.__genreIds + + def _set_genreIds(self, value): + if not isinstance(value, list): + raise TypeError("genreIds must be list") + if not all(isinstance(i, str) for i in value): + raise TypeError("genreIds list values must be str") + + self.__genreIds = value + + genreIds = property(_get_genreIds, _set_genreIds) + + def _get_primaryGenreName(self): + return self.__primaryGenreName + + def _set_primaryGenreName(self, value): + if not isinstance(value, str): + raise TypeError("primaryGenreName must be str") + + self.__primaryGenreName = value + + primaryGenreName = property(_get_primaryGenreName, _set_primaryGenreName) + + def _get_trackId(self): + return self.__trackId + + def _set_trackId(self, value): + if not isinstance(value, int): + raise TypeError("trackId must be int") + + self.__trackId = value + + trackId = property(_get_trackId, _set_trackId) + + def _get_trackName(self): + return self.__trackName + + def _set_trackName(self, value): + if not isinstance(value, str): + raise TypeError("trackName must be str") + + self.__trackName = value + + trackName = property(_get_trackName, _set_trackName) + + def _get_sellerName(self): + return self.__sellerName + + def _set_sellerName(self, value): + if not isinstance(value, str): + raise TypeError("sellerName must be str") + + self.__sellerName = value + + sellerName = property(_get_sellerName, _set_sellerName) + + def _get_isVppDeviceBasedLicensingEnabled(self): + return self.__isVppDeviceBasedLicensingEnabled + + def _set_isVppDeviceBasedLicensingEnabled(self, value): + if not isinstance(value, bool): + raise TypeError("isVppDeviceBasedLicensingEnabled must be bool") + + self.__isVppDeviceBasedLicensingEnabled = value + + isVppDeviceBasedLicensingEnabled = property( + _get_isVppDeviceBasedLicensingEnabled, _set_isVppDeviceBasedLicensingEnabled + ) + + def _get_currentVersionReleaseDate(self): + return self.__currentVersionReleaseDate + + def _set_currentVersionReleaseDate(self, value): + if not isinstance(value, str): + raise TypeError("currentVersionReleaseDate must be str") + + self.__currentVersionReleaseDate = value + + currentVersionReleaseDate = property( + _get_currentVersionReleaseDate, _set_currentVersionReleaseDate + ) + + def _get_releaseNotes(self): + return self.__releaseNotes + + def _set_releaseNotes(self, value): + if not isinstance(value, str): + raise TypeError("releaseNotes must be str") + + self.__releaseNotes = value + + releaseNotes = property(_get_releaseNotes, _set_releaseNotes) + + def _get_primaryGenreId(self): + return self.__primaryGenreId + + def _set_primaryGenreId(self, value): + if not isinstance(value, int): + raise TypeError("primaryGenreId must be int") + + self.__primaryGenreId = value + + primaryGenreId = property(_get_primaryGenreId, _set_primaryGenreId) + + def _get_currency(self): + return self.__currency + + def _set_currency(self, value): + if not isinstance(value, str): + raise TypeError("currency must be str") + + self.__currency = value + + currency = property(_get_currency, _set_currency) + + def _get_version(self): + return self.__version + + def _set_version(self, value): + if not isinstance(value, str): + raise TypeError("version must be str") + + self.__version = value + + version = property(_get_version, _set_version) + + def _get_wrapperType(self): + return self.__wrapperType + + def _set_wrapperType(self, value): + if not isinstance(value, str): + raise TypeError("wrapperType must be str") + + self.__wrapperType = value + + wrapperType = property(_get_wrapperType, _set_wrapperType) + + def _get_artistId(self): + return self.__artistId + + def _set_artistId(self, value): + if not isinstance(value, int): + raise TypeError("artistId must be int") + + self.__artistId = value + + artistId = property(_get_artistId, _set_artistId) + + def _get_artistName(self): + return self.__artistName + + def _set_artistName(self, value): + if not isinstance(value, str): + raise TypeError("artistName must be str") + + self.__artistName = value + + artistName = property(_get_artistName, _set_artistName) + + def _get_genres(self): + return self.__genres + + def _set_genres(self, value): + if not isinstance(value, list): + raise TypeError("genres must be list") + if not all(isinstance(i, str) for i in value): + raise TypeError("genres list values must be str") + + self.__genres = value + + genres = property(_get_genres, _set_genres) + + def _get_price(self): + return self.__price + + def _set_price(self, value): + if not isinstance(value, float): + raise TypeError("price must be float") + + self.__price = value + + price = property(_get_price, _set_price) + + def _get_description(self): + return self.__description + + def _set_description(self, value): + if not isinstance(value, str): + raise TypeError("description must be str") + + self.__description = value + + description = property(_get_description, _set_description) + + def _get_bundleId(self): + return self.__bundleId + + def _set_bundleId(self, value): + if not isinstance(value, str): + raise TypeError("bundleId must be str") + + self.__bundleId = value + + bundleId = property(_get_bundleId, _set_bundleId) + + def _get_userRatingCount(self): + return self.__userRatingCount + + def _set_userRatingCount(self, value): + if not isinstance(value, int): + raise TypeError("userRatingCount must be int") + + self.__userRatingCount = value + + userRatingCount = property(_get_userRatingCount, _set_userRatingCount) + + @staticmethod + def from_dict(d): + v = {} + if "appletvScreenshotUrls" in d: + v["appletvScreenshotUrls"] = [ + float.from_dict(p) if hasattr(float, "from_dict") else p + for p in d["appletvScreenshotUrls"] + ] + if "screenshotUrls" in d: + v["screenshotUrls"] = [ + str.from_dict(p) if hasattr(str, "from_dict") else p + for p in d["screenshotUrls"] + ] + if "ipadScreenshotUrls" in d: + v["ipadScreenshotUrls"] = [ + str.from_dict(p) if hasattr(str, "from_dict") else p + for p in d["ipadScreenshotUrls"] + ] + if "artworkUrl60" in d: + v["artworkUrl60"] = ( + str.from_dict(d["artworkUrl60"]) + if hasattr(str, "from_dict") + else d["artworkUrl60"] + ) + if "artworkUrl512" in d: + v["artworkUrl512"] = ( + str.from_dict(d["artworkUrl512"]) + if hasattr(str, "from_dict") + else d["artworkUrl512"] + ) + if "artworkUrl100" in d: + v["artworkUrl100"] = ( + str.from_dict(d["artworkUrl100"]) + if hasattr(str, "from_dict") + else d["artworkUrl100"] + ) + if "artistViewUrl" in d: + v["artistViewUrl"] = ( + str.from_dict(d["artistViewUrl"]) + if hasattr(str, "from_dict") + else d["artistViewUrl"] + ) + if "supportedDevices" in d: + v["supportedDevices"] = [ + str.from_dict(p) if hasattr(str, "from_dict") else p + for p in d["supportedDevices"] + ] + if "advisories" in d: + v["advisories"] = [ + float.from_dict(p) if hasattr(float, "from_dict") else p + for p in d["advisories"] + ] + if "isGameCenterEnabled" in d: + v["isGameCenterEnabled"] = ( + bool.from_dict(d["isGameCenterEnabled"]) + if hasattr(bool, "from_dict") + else d["isGameCenterEnabled"] + ) + if "kind" in d: + v["kind"] = ( + str.from_dict(d["kind"]) if hasattr(str, "from_dict") else d["kind"] + ) + if "features" in d: + v["features"] = [ + str.from_dict(p) if hasattr(str, "from_dict") else p + for p in d["features"] + ] + if "minimumOsVersion" in d: + v["minimumOsVersion"] = ( + str.from_dict(d["minimumOsVersion"]) + if hasattr(str, "from_dict") + else d["minimumOsVersion"] + ) + if "trackCensoredName" in d: + v["trackCensoredName"] = ( + str.from_dict(d["trackCensoredName"]) + if hasattr(str, "from_dict") + else d["trackCensoredName"] + ) + if "languageCodesISO2A" in d: + v["languageCodesISO2A"] = [ + str.from_dict(p) if hasattr(str, "from_dict") else p + for p in d["languageCodesISO2A"] + ] + if "fileSizeBytes" in d: + v["fileSizeBytes"] = ( + str.from_dict(d["fileSizeBytes"]) + if hasattr(str, "from_dict") + else d["fileSizeBytes"] + ) + if "formattedPrice" in d: + v["formattedPrice"] = ( + str.from_dict(d["formattedPrice"]) + if hasattr(str, "from_dict") + else d["formattedPrice"] + ) + if "contentAdvisoryRating" in d: + v["contentAdvisoryRating"] = ( + str.from_dict(d["contentAdvisoryRating"]) + if hasattr(str, "from_dict") + else d["contentAdvisoryRating"] + ) + if "averageUserRatingForCurrentVersion" in d: + v["averageUserRatingForCurrentVersion"] = ( + float.from_dict(d["averageUserRatingForCurrentVersion"]) + if hasattr(float, "from_dict") + else d["averageUserRatingForCurrentVersion"] + ) + if "userRatingCountForCurrentVersion" in d: + v["userRatingCountForCurrentVersion"] = ( + int.from_dict(d["userRatingCountForCurrentVersion"]) + if hasattr(int, "from_dict") + else d["userRatingCountForCurrentVersion"] + ) + if "averageUserRating" in d: + v["averageUserRating"] = ( + float.from_dict(d["averageUserRating"]) + if hasattr(float, "from_dict") + else d["averageUserRating"] + ) + if "trackViewUrl" in d: + v["trackViewUrl"] = ( + str.from_dict(d["trackViewUrl"]) + if hasattr(str, "from_dict") + else d["trackViewUrl"] + ) + if "trackContentRating" in d: + v["trackContentRating"] = ( + str.from_dict(d["trackContentRating"]) + if hasattr(str, "from_dict") + else d["trackContentRating"] + ) + if "releaseDate" in d: + v["releaseDate"] = ( + str.from_dict(d["releaseDate"]) + if hasattr(str, "from_dict") + else d["releaseDate"] + ) + if "genreIds" in d: + v["genreIds"] = [ + str.from_dict(p) if hasattr(str, "from_dict") else p + for p in d["genreIds"] + ] + if "primaryGenreName" in d: + v["primaryGenreName"] = ( + str.from_dict(d["primaryGenreName"]) + if hasattr(str, "from_dict") + else d["primaryGenreName"] + ) + if "trackId" in d: + v["trackId"] = ( + int.from_dict(d["trackId"]) + if hasattr(int, "from_dict") + else d["trackId"] + ) + if "trackName" in d: + v["trackName"] = ( + str.from_dict(d["trackName"]) + if hasattr(str, "from_dict") + else d["trackName"] + ) + if "sellerName" in d: + v["sellerName"] = ( + str.from_dict(d["sellerName"]) + if hasattr(str, "from_dict") + else d["sellerName"] + ) + if "isVppDeviceBasedLicensingEnabled" in d: + v["isVppDeviceBasedLicensingEnabled"] = ( + bool.from_dict(d["isVppDeviceBasedLicensingEnabled"]) + if hasattr(bool, "from_dict") + else d["isVppDeviceBasedLicensingEnabled"] + ) + if "currentVersionReleaseDate" in d: + v["currentVersionReleaseDate"] = ( + str.from_dict(d["currentVersionReleaseDate"]) + if hasattr(str, "from_dict") + else d["currentVersionReleaseDate"] + ) + if "releaseNotes" in d: + v["releaseNotes"] = ( + str.from_dict(d["releaseNotes"]) + if hasattr(str, "from_dict") + else d["releaseNotes"] + ) + if "primaryGenreId" in d: + v["primaryGenreId"] = ( + int.from_dict(d["primaryGenreId"]) + if hasattr(int, "from_dict") + else d["primaryGenreId"] + ) + if "currency" in d: + v["currency"] = ( + str.from_dict(d["currency"]) + if hasattr(str, "from_dict") + else d["currency"] + ) + if "version" in d: + v["version"] = ( + str.from_dict(d["version"]) + if hasattr(str, "from_dict") + else d["version"] + ) + if "wrapperType" in d: + v["wrapperType"] = ( + str.from_dict(d["wrapperType"]) + if hasattr(str, "from_dict") + else d["wrapperType"] + ) + if "artistId" in d: + v["artistId"] = ( + int.from_dict(d["artistId"]) + if hasattr(int, "from_dict") + else d["artistId"] + ) + if "artistName" in d: + v["artistName"] = ( + str.from_dict(d["artistName"]) + if hasattr(str, "from_dict") + else d["artistName"] + ) + if "genres" in d: + v["genres"] = [ + str.from_dict(p) if hasattr(str, "from_dict") else p + for p in d["genres"] + ] + if "price" in d: + v["price"] = ( + float.from_dict(d["price"]) + if hasattr(float, "from_dict") + else d["price"] + ) + if "description" in d: + v["description"] = ( + str.from_dict(d["description"]) + if hasattr(str, "from_dict") + else d["description"] + ) + if "bundleId" in d: + v["bundleId"] = ( + str.from_dict(d["bundleId"]) + if hasattr(str, "from_dict") + else d["bundleId"] + ) + if "userRatingCount" in d: + v["userRatingCount"] = ( + int.from_dict(d["userRatingCount"]) + if hasattr(int, "from_dict") + else d["userRatingCount"] + ) + return ItunesLookupResp._results(**v) + + def as_dict(self): + d = {} + if self.__appletvScreenshotUrls is not None: + d["appletvScreenshotUrls"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__appletvScreenshotUrls + ] + if self.__screenshotUrls is not None: + d["screenshotUrls"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__screenshotUrls + ] + if self.__ipadScreenshotUrls is not None: + d["ipadScreenshotUrls"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__ipadScreenshotUrls + ] + if self.__artworkUrl60 is not None: + d["artworkUrl60"] = ( + self.__artworkUrl60.as_dict() + if hasattr(self.__artworkUrl60, "as_dict") + else self.__artworkUrl60 + ) + if self.__artworkUrl512 is not None: + d["artworkUrl512"] = ( + self.__artworkUrl512.as_dict() + if hasattr(self.__artworkUrl512, "as_dict") + else self.__artworkUrl512 + ) + if self.__artworkUrl100 is not None: + d["artworkUrl100"] = ( + self.__artworkUrl100.as_dict() + if hasattr(self.__artworkUrl100, "as_dict") + else self.__artworkUrl100 + ) + if self.__artistViewUrl is not None: + d["artistViewUrl"] = ( + self.__artistViewUrl.as_dict() + if hasattr(self.__artistViewUrl, "as_dict") + else self.__artistViewUrl + ) + if self.__supportedDevices is not None: + d["supportedDevices"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__supportedDevices + ] + if self.__advisories is not None: + d["advisories"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__advisories + ] + if self.__isGameCenterEnabled is not None: + d["isGameCenterEnabled"] = ( + self.__isGameCenterEnabled.as_dict() + if hasattr(self.__isGameCenterEnabled, "as_dict") + else self.__isGameCenterEnabled + ) + if self.__kind is not None: + d["kind"] = ( + self.__kind.as_dict() + if hasattr(self.__kind, "as_dict") + else self.__kind + ) + if self.__features is not None: + d["features"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__features + ] + if self.__minimumOsVersion is not None: + d["minimumOsVersion"] = ( + self.__minimumOsVersion.as_dict() + if hasattr(self.__minimumOsVersion, "as_dict") + else self.__minimumOsVersion + ) + if self.__trackCensoredName is not None: + d["trackCensoredName"] = ( + self.__trackCensoredName.as_dict() + if hasattr(self.__trackCensoredName, "as_dict") + else self.__trackCensoredName + ) + if self.__languageCodesISO2A is not None: + d["languageCodesISO2A"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__languageCodesISO2A + ] + if self.__fileSizeBytes is not None: + d["fileSizeBytes"] = ( + self.__fileSizeBytes.as_dict() + if hasattr(self.__fileSizeBytes, "as_dict") + else self.__fileSizeBytes + ) + if self.__formattedPrice is not None: + d["formattedPrice"] = ( + self.__formattedPrice.as_dict() + if hasattr(self.__formattedPrice, "as_dict") + else self.__formattedPrice + ) + if self.__contentAdvisoryRating is not None: + d["contentAdvisoryRating"] = ( + self.__contentAdvisoryRating.as_dict() + if hasattr(self.__contentAdvisoryRating, "as_dict") + else self.__contentAdvisoryRating + ) + if self.__averageUserRatingForCurrentVersion is not None: + d["averageUserRatingForCurrentVersion"] = ( + self.__averageUserRatingForCurrentVersion.as_dict() + if hasattr(self.__averageUserRatingForCurrentVersion, "as_dict") + else self.__averageUserRatingForCurrentVersion + ) + if self.__userRatingCountForCurrentVersion is not None: + d["userRatingCountForCurrentVersion"] = ( + self.__userRatingCountForCurrentVersion.as_dict() + if hasattr(self.__userRatingCountForCurrentVersion, "as_dict") + else self.__userRatingCountForCurrentVersion + ) + if self.__averageUserRating is not None: + d["averageUserRating"] = ( + self.__averageUserRating.as_dict() + if hasattr(self.__averageUserRating, "as_dict") + else self.__averageUserRating + ) + if self.__trackViewUrl is not None: + d["trackViewUrl"] = ( + self.__trackViewUrl.as_dict() + if hasattr(self.__trackViewUrl, "as_dict") + else self.__trackViewUrl + ) + if self.__trackContentRating is not None: + d["trackContentRating"] = ( + self.__trackContentRating.as_dict() + if hasattr(self.__trackContentRating, "as_dict") + else self.__trackContentRating + ) + if self.__releaseDate is not None: + d["releaseDate"] = ( + self.__releaseDate.as_dict() + if hasattr(self.__releaseDate, "as_dict") + else self.__releaseDate + ) + if self.__genreIds is not None: + d["genreIds"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__genreIds + ] + if self.__primaryGenreName is not None: + d["primaryGenreName"] = ( + self.__primaryGenreName.as_dict() + if hasattr(self.__primaryGenreName, "as_dict") + else self.__primaryGenreName + ) + if self.__trackId is not None: + d["trackId"] = ( + self.__trackId.as_dict() + if hasattr(self.__trackId, "as_dict") + else self.__trackId + ) + if self.__trackName is not None: + d["trackName"] = ( + self.__trackName.as_dict() + if hasattr(self.__trackName, "as_dict") + else self.__trackName + ) + if self.__sellerName is not None: + d["sellerName"] = ( + self.__sellerName.as_dict() + if hasattr(self.__sellerName, "as_dict") + else self.__sellerName + ) + if self.__isVppDeviceBasedLicensingEnabled is not None: + d["isVppDeviceBasedLicensingEnabled"] = ( + self.__isVppDeviceBasedLicensingEnabled.as_dict() + if hasattr(self.__isVppDeviceBasedLicensingEnabled, "as_dict") + else self.__isVppDeviceBasedLicensingEnabled + ) + if self.__currentVersionReleaseDate is not None: + d["currentVersionReleaseDate"] = ( + self.__currentVersionReleaseDate.as_dict() + if hasattr(self.__currentVersionReleaseDate, "as_dict") + else self.__currentVersionReleaseDate + ) + if self.__releaseNotes is not None: + d["releaseNotes"] = ( + self.__releaseNotes.as_dict() + if hasattr(self.__releaseNotes, "as_dict") + else self.__releaseNotes + ) + if self.__primaryGenreId is not None: + d["primaryGenreId"] = ( + self.__primaryGenreId.as_dict() + if hasattr(self.__primaryGenreId, "as_dict") + else self.__primaryGenreId + ) + if self.__currency is not None: + d["currency"] = ( + self.__currency.as_dict() + if hasattr(self.__currency, "as_dict") + else self.__currency + ) + if self.__version is not None: + d["version"] = ( + self.__version.as_dict() + if hasattr(self.__version, "as_dict") + else self.__version + ) + if self.__wrapperType is not None: + d["wrapperType"] = ( + self.__wrapperType.as_dict() + if hasattr(self.__wrapperType, "as_dict") + else self.__wrapperType + ) + if self.__artistId is not None: + d["artistId"] = ( + self.__artistId.as_dict() + if hasattr(self.__artistId, "as_dict") + else self.__artistId + ) + if self.__artistName is not None: + d["artistName"] = ( + self.__artistName.as_dict() + if hasattr(self.__artistName, "as_dict") + else self.__artistName + ) + if self.__genres is not None: + d["genres"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__genres + ] + if self.__price is not None: + d["price"] = ( + self.__price.as_dict() + if hasattr(self.__price, "as_dict") + else self.__price + ) + if self.__description is not None: + d["description"] = ( + self.__description.as_dict() + if hasattr(self.__description, "as_dict") + else self.__description + ) + if self.__bundleId is not None: + d["bundleId"] = ( + self.__bundleId.as_dict() + if hasattr(self.__bundleId, "as_dict") + else self.__bundleId + ) + if self.__userRatingCount is not None: + d["userRatingCount"] = ( + self.__userRatingCount.as_dict() + if hasattr(self.__userRatingCount, "as_dict") + else self.__userRatingCount + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__appletvScreenshotUrls[:20] + if isinstance(self.__appletvScreenshotUrls, bytes) + else self.__appletvScreenshotUrls + ), + limitedRepr( + self.__screenshotUrls[:20] + if isinstance(self.__screenshotUrls, bytes) + else self.__screenshotUrls + ), + limitedRepr( + self.__ipadScreenshotUrls[:20] + if isinstance(self.__ipadScreenshotUrls, bytes) + else self.__ipadScreenshotUrls + ), + limitedRepr( + self.__artworkUrl60[:20] + if isinstance(self.__artworkUrl60, bytes) + else self.__artworkUrl60 + ), + limitedRepr( + self.__artworkUrl512[:20] + if isinstance(self.__artworkUrl512, bytes) + else self.__artworkUrl512 + ), + limitedRepr( + self.__artworkUrl100[:20] + if isinstance(self.__artworkUrl100, bytes) + else self.__artworkUrl100 + ), + limitedRepr( + self.__artistViewUrl[:20] + if isinstance(self.__artistViewUrl, bytes) + else self.__artistViewUrl + ), + limitedRepr( + self.__supportedDevices[:20] + if isinstance(self.__supportedDevices, bytes) + else self.__supportedDevices + ), + limitedRepr( + self.__advisories[:20] + if isinstance(self.__advisories, bytes) + else self.__advisories + ), + limitedRepr( + self.__isGameCenterEnabled[:20] + if isinstance(self.__isGameCenterEnabled, bytes) + else self.__isGameCenterEnabled + ), + limitedRepr( + self.__kind[:20] if isinstance(self.__kind, bytes) else self.__kind + ), + limitedRepr( + self.__features[:20] + if isinstance(self.__features, bytes) + else self.__features + ), + limitedRepr( + self.__minimumOsVersion[:20] + if isinstance(self.__minimumOsVersion, bytes) + else self.__minimumOsVersion + ), + limitedRepr( + self.__trackCensoredName[:20] + if isinstance(self.__trackCensoredName, bytes) + else self.__trackCensoredName + ), + limitedRepr( + self.__languageCodesISO2A[:20] + if isinstance(self.__languageCodesISO2A, bytes) + else self.__languageCodesISO2A + ), + limitedRepr( + self.__fileSizeBytes[:20] + if isinstance(self.__fileSizeBytes, bytes) + else self.__fileSizeBytes + ), + limitedRepr( + self.__formattedPrice[:20] + if isinstance(self.__formattedPrice, bytes) + else self.__formattedPrice + ), + limitedRepr( + self.__contentAdvisoryRating[:20] + if isinstance(self.__contentAdvisoryRating, bytes) + else self.__contentAdvisoryRating + ), + limitedRepr( + self.__averageUserRatingForCurrentVersion[:20] + if isinstance(self.__averageUserRatingForCurrentVersion, bytes) + else self.__averageUserRatingForCurrentVersion + ), + limitedRepr( + self.__userRatingCountForCurrentVersion[:20] + if isinstance(self.__userRatingCountForCurrentVersion, bytes) + else self.__userRatingCountForCurrentVersion + ), + limitedRepr( + self.__averageUserRating[:20] + if isinstance(self.__averageUserRating, bytes) + else self.__averageUserRating + ), + limitedRepr( + self.__trackViewUrl[:20] + if isinstance(self.__trackViewUrl, bytes) + else self.__trackViewUrl + ), + limitedRepr( + self.__trackContentRating[:20] + if isinstance(self.__trackContentRating, bytes) + else self.__trackContentRating + ), + limitedRepr( + self.__releaseDate[:20] + if isinstance(self.__releaseDate, bytes) + else self.__releaseDate + ), + limitedRepr( + self.__genreIds[:20] + if isinstance(self.__genreIds, bytes) + else self.__genreIds + ), + limitedRepr( + self.__primaryGenreName[:20] + if isinstance(self.__primaryGenreName, bytes) + else self.__primaryGenreName + ), + limitedRepr( + self.__trackId[:20] + if isinstance(self.__trackId, bytes) + else self.__trackId + ), + limitedRepr( + self.__trackName[:20] + if isinstance(self.__trackName, bytes) + else self.__trackName + ), + limitedRepr( + self.__sellerName[:20] + if isinstance(self.__sellerName, bytes) + else self.__sellerName + ), + limitedRepr( + self.__isVppDeviceBasedLicensingEnabled[:20] + if isinstance(self.__isVppDeviceBasedLicensingEnabled, bytes) + else self.__isVppDeviceBasedLicensingEnabled + ), + limitedRepr( + self.__currentVersionReleaseDate[:20] + if isinstance(self.__currentVersionReleaseDate, bytes) + else self.__currentVersionReleaseDate + ), + limitedRepr( + self.__releaseNotes[:20] + if isinstance(self.__releaseNotes, bytes) + else self.__releaseNotes + ), + limitedRepr( + self.__primaryGenreId[:20] + if isinstance(self.__primaryGenreId, bytes) + else self.__primaryGenreId + ), + limitedRepr( + self.__currency[:20] + if isinstance(self.__currency, bytes) + else self.__currency + ), + limitedRepr( + self.__version[:20] + if isinstance(self.__version, bytes) + else self.__version + ), + limitedRepr( + self.__wrapperType[:20] + if isinstance(self.__wrapperType, bytes) + else self.__wrapperType + ), + limitedRepr( + self.__artistId[:20] + if isinstance(self.__artistId, bytes) + else self.__artistId + ), + limitedRepr( + self.__artistName[:20] + if isinstance(self.__artistName, bytes) + else self.__artistName + ), + limitedRepr( + self.__genres[:20] + if isinstance(self.__genres, bytes) + else self.__genres + ), + limitedRepr( + self.__price[:20] + if isinstance(self.__price, bytes) + else self.__price + ), + limitedRepr( + self.__description[:20] + if isinstance(self.__description, bytes) + else self.__description + ), + limitedRepr( + self.__bundleId[:20] + if isinstance(self.__bundleId, bytes) + else self.__bundleId + ), + limitedRepr( + self.__userRatingCount[:20] + if isinstance(self.__userRatingCount, bytes) + else self.__userRatingCount + ), + ) + + _types_map = { + "resultCount": {"type": int, "subtype": None}, + "results": {"type": list, "subtype": _results}, + } + _formats_map = {} + _validations_map = { + "resultCount": { + "required": True, + }, + "results": { + "required": True, + }, + } + + def __init__(self, resultCount: int = None, results: List[_results] = None): + pass + self.__resultCount = resultCount + self.__results = results + + def _get_resultCount(self): + return self.__resultCount + + def _set_resultCount(self, value): + if not isinstance(value, int): + raise TypeError("resultCount must be int") + + self.__resultCount = value + + resultCount = property(_get_resultCount, _set_resultCount) + + def _get_results(self): + return self.__results + + def _set_results(self, value): + if not isinstance(value, list): + raise TypeError("results must be list") + if not all(isinstance(i, ItunesLookupResp._results) for i in value): + raise TypeError("results list values must be ItunesLookupResp._results") + + self.__results = value + + results = property(_get_results, _set_results) + + @staticmethod + def from_dict(d): + v = {} + if "resultCount" in d: + v["resultCount"] = ( + int.from_dict(d["resultCount"]) + if hasattr(int, "from_dict") + else d["resultCount"] + ) + if "results" in d: + v["results"] = [ + ItunesLookupResp._results.from_dict(p) + if hasattr(ItunesLookupResp._results, "from_dict") + else p + for p in d["results"] + ] + return ItunesLookupResp(**v) + + def as_dict(self): + d = {} + if self.__resultCount is not None: + d["resultCount"] = ( + self.__resultCount.as_dict() + if hasattr(self.__resultCount, "as_dict") + else self.__resultCount + ) + if self.__results is not None: + d["results"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__results + ] + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__resultCount[:20] + if isinstance(self.__resultCount, bytes) + else self.__resultCount + ), + limitedRepr( + self.__results[:20] + if isinstance(self.__results, bytes) + else self.__results + ), + ) diff --git a/src_mac/ipatool-py/reqs/schemas/schema_defs/__init__.py b/src_mac/ipatool-py/reqs/schemas/schema_defs/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/src_mac/ipatool-py/reqs/schemas/schema_defs/__main__.py b/src_mac/ipatool-py/reqs/schemas/schema_defs/__main__.py new file mode 100755 index 0000000..9cce5a5 --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/schema_defs/__main__.py @@ -0,0 +1,12 @@ +import os +import os.path as path +import subprocess + +curpath = path.dirname(__file__) +outpath = path.dirname(curpath) +for p in os.listdir(curpath): + if not p.endswith('.json'): + continue + #subprocess.call(["jsonschema2popo2", "--translate-properties", "--use-types", "-o", path.join(outpath, p.split('.')[0] + '.py'), path.join(curpath, p)]) + print("Converting %s" % p) + subprocess.call(["jsonschema2popo2", "--use-types", "-o", path.join(outpath, p.split('.')[0] + '.py'), path.join(curpath, p)]) \ No newline at end of file diff --git a/src_mac/ipatool-py/reqs/schemas/schema_defs/itunes_lookup_resp.json b/src_mac/ipatool-py/reqs/schemas/schema_defs/itunes_lookup_resp.json new file mode 100755 index 0000000..e9524c3 --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/schema_defs/itunes_lookup_resp.json @@ -0,0 +1,222 @@ +{ + "title": "iTunes Lookup Resp", + "type": "object", + "properties": { + "resultCount": { + "type": "integer" + }, + "results": { + "type": "array", + "items": { + "type": "object", + "properties": { + "appletvScreenshotUrls": { + "type": "array", + "items": { + "type": ["number","string","boolean","object","array", "null"] + } + }, + "screenshotUrls": { + "type": "array", + "items": { + "type": "string" + } + }, + "ipadScreenshotUrls": { + "type": "array", + "items": { + "type": "string" + } + }, + "artworkUrl60": { + "type": "string" + }, + "artworkUrl512": { + "type": "string" + }, + "artworkUrl100": { + "type": "string" + }, + "artistViewUrl": { + "type": "string" + }, + "supportedDevices": { + "type": "array", + "items": { + "type": "string" + } + }, + "advisories": { + "type": "array", + "items": { + "type": ["number","string","boolean","object","array", "null"] + } + }, + "isGameCenterEnabled": { + "type": "boolean" + }, + "kind": { + "type": "string" + }, + "features": { + "type": "array", + "items": { + "type": "string" + } + }, + "minimumOsVersion": { + "type": "string" + }, + "trackCensoredName": { + "type": "string" + }, + "languageCodesISO2A": { + "type": "array", + "items": { + "type": "string" + } + }, + "fileSizeBytes": { + "type": "string" + }, + "formattedPrice": { + "type": "string" + }, + "contentAdvisoryRating": { + "type": "string" + }, + "averageUserRatingForCurrentVersion": { + "type": "number" + }, + "userRatingCountForCurrentVersion": { + "type": "integer" + }, + "averageUserRating": { + "type": "number" + }, + "trackViewUrl": { + "type": "string" + }, + "trackContentRating": { + "type": "string" + }, + "releaseDate": { + "type": "string" + }, + "genreIds": { + "type": "array", + "items": { + "type": "string" + } + }, + "primaryGenreName": { + "type": "string" + }, + "trackId": { + "type": "integer" + }, + "trackName": { + "type": "string" + }, + "sellerName": { + "type": "string" + }, + "isVppDeviceBasedLicensingEnabled": { + "type": "boolean" + }, + "currentVersionReleaseDate": { + "type": "string" + }, + "releaseNotes": { + "type": "string" + }, + "primaryGenreId": { + "type": "integer" + }, + "currency": { + "type": "string" + }, + "version": { + "type": "string" + }, + "wrapperType": { + "type": "string" + }, + "artistId": { + "type": "integer" + }, + "artistName": { + "type": "string" + }, + "genres": { + "type": "array", + "items": { + "type": "string" + } + }, + "price": { + "type": "number" + }, + "description": { + "type": "string" + }, + "bundleId": { + "type": "string" + }, + "userRatingCount": { + "type": "integer" + } + }, + "required": [ + "appletvScreenshotUrls", + "screenshotUrls", + "ipadScreenshotUrls", + "artworkUrl60", + "artworkUrl512", + "artworkUrl100", + "artistViewUrl", + "supportedDevices", + "advisories", + "isGameCenterEnabled", + "kind", + "features", + "minimumOsVersion", + "trackCensoredName", + "languageCodesISO2A", + "fileSizeBytes", + "formattedPrice", + "contentAdvisoryRating", + "averageUserRatingForCurrentVersion", + "userRatingCountForCurrentVersion", + "averageUserRating", + "trackViewUrl", + "trackContentRating", + "releaseDate", + "genreIds", + "primaryGenreName", + "trackId", + "trackName", + "sellerName", + "isVppDeviceBasedLicensingEnabled", + "currentVersionReleaseDate", + "releaseNotes", + "primaryGenreId", + "currency", + "version", + "wrapperType", + "artistId", + "artistName", + "genres", + "price", + "description", + "bundleId", + "userRatingCount" + ] + } + } + }, + "required": [ + "resultCount", + "results" + ] +} \ No newline at end of file diff --git a/src_mac/ipatool-py/reqs/schemas/schema_defs/store_authenticate_req.json b/src_mac/ipatool-py/reqs/schemas/schema_defs/store_authenticate_req.json new file mode 100755 index 0000000..1a713bc --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/schema_defs/store_authenticate_req.json @@ -0,0 +1,37 @@ +{ + "title": "Store Authenticate Req", + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "appleId": { + "type": "string" + }, + "attempt": { + "type": "string" + }, + "createSession": { + "type": "string" + }, + "guid": { + "type": "string" + }, + "password": { + "type": "string" + }, + "rmp": { + "type": "string" + }, + "why": { + "type": "string" + } + }, + "required": [ + "appleId", + "attempt", + "createSession", + "guid", + "password", + "rmp", + "why" + ] +} \ No newline at end of file diff --git a/src_mac/ipatool-py/reqs/schemas/schema_defs/store_authenticate_resp.json b/src_mac/ipatool-py/reqs/schemas/schema_defs/store_authenticate_resp.json new file mode 100755 index 0000000..18a5fa3 --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/schema_defs/store_authenticate_resp.json @@ -0,0 +1,324 @@ +{ + "title": "Store Authenticate Resp", + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "pings": { + "type": "array", + "items": { + "type": ["number","string","boolean","object","array", "null"] + } + }, + "cancel-purchase-batch": { + "type": "boolean" + }, + "customerMessage": { + "type": "string" + }, + "failureType": { + "type": "string" + }, + "accountInfo": { + "type": "object", + "properties": { + "appleId": { + "type": "string" + }, + "address": { + "type": "object", + "properties": { + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + }, + "required": [ + "firstName", + "lastName" + ] + } + }, + "required": [ + "appleId", + "address" + ] + }, + "passwordToken": { + "type": "string" + }, + "clearToken": { + "type": "string" + }, + "m-allowed": { + "type": "boolean" + }, + "is-cloud-enabled": { + "type": "string" + }, + "dsPersonId": { + "type": "string" + }, + "creditDisplay": { + "type": "string" + }, + "creditBalance": { + "type": "string" + }, + "freeSongBalance": { + "type": "string" + }, + "isManagedStudent": { + "type": "boolean" + }, + "action": { + "type": "object", + "properties": { + "kind": { + "type": "string" + } + }, + "required": [ + "kind" + ] + }, + "subscriptionStatus": { + "type": "object", + "properties": { + "terms": { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "latestTerms": { + "type": "integer" + }, + "agreedToTerms": { + "type": "integer" + }, + "source": { + "type": "string" + } + }, + "required": [ + "type", + "latestTerms", + "agreedToTerms", + "source" + ] + } + }, + "account": { + "type": "object", + "properties": { + "isMinor": { + "type": "boolean" + }, + "suspectUnderage": { + "type": "boolean" + } + }, + "required": [ + "isMinor", + "suspectUnderage" + ] + }, + "family": { + "type": "object", + "properties": { + "hasFamily": { + "type": "boolean" + } + }, + "required": [ + "hasFamily" + ] + } + }, + "required": [ + "terms", + "account", + "family" + ] + }, + "accountFlags": { + "type": "object", + "properties": { + "personalization": { + "type": "boolean" + }, + "underThirteen": { + "type": "boolean" + }, + "identityLastVerified": { + "type": "integer" + }, + "verifiedExpirationDate": { + "type": "integer" + }, + "retailDemo": { + "type": "boolean" + }, + "autoPlay": { + "type": "boolean" + }, + "isDisabledAccount": { + "type": "boolean" + }, + "isRestrictedAccount": { + "type": "boolean" + }, + "isManagedAccount": { + "type": "boolean" + }, + "isInRestrictedRegion": { + "type": "boolean" + }, + "accountFlagsVersion": { + "type": "integer" + }, + "hasAgreedToTerms": { + "type": "boolean" + }, + "hasAgreedToAppClipTerms": { + "type": "boolean" + }, + "hasWatchHardwareOffer": { + "type": "boolean" + }, + "isInFamily": { + "type": "boolean" + }, + "hasSubscriptionFamilySharingEnabled": { + "type": "boolean" + } + }, + "required": [ + "personalization", + "underThirteen", + "identityLastVerified", + "verifiedExpirationDate", + "retailDemo", + "autoPlay", + "isDisabledAccount", + "isRestrictedAccount", + "isManagedAccount", + "isInRestrictedRegion", + "accountFlagsVersion", + "hasAgreedToTerms", + "hasAgreedToAppClipTerms", + "hasWatchHardwareOffer", + "isInFamily", + "hasSubscriptionFamilySharingEnabled" + ] + }, + "status": { + "type": "integer" + }, + "download-queue-info": { + "type": "object", + "properties": { + "download-queue-item-count": { + "type": "integer" + }, + "dsid": { + "type": "integer" + }, + "is-auto-download-machine": { + "type": "boolean" + } + }, + "required": [ + "download-queue-item-count", + "dsid", + "is-auto-download-machine" + ] + }, + "privacyAcknowledgement": { + "type": "object", + "properties": { + "com.apple.onboarding.appstore": { + "type": "integer" + }, + "com.apple.onboarding.applemusic": { + "type": "integer" + }, + "com.apple.onboarding.videos": { + "type": "integer" + }, + "com.apple.onboarding.itunesstore": { + "type": "integer" + }, + "com.apple.onboarding.itunesu": { + "type": "integer" + }, + "com.apple.onboarding.applearcade": { + "type": "integer" + } + }, + "required": [ + "com.apple.onboarding.appstore", + "com.apple.onboarding.applemusic", + "com.apple.onboarding.videos", + "com.apple.onboarding.itunesstore", + "com.apple.onboarding.itunesu", + "com.apple.onboarding.applearcade" + ] + }, + "dialog": { + "type": "object", + "properties": { + "m-allowed": { + "type": "boolean" + }, + "message": { + "type": "string" + }, + "explanation": { + "type": "string" + }, + "defaultButton": { + "type": "string" + }, + "okButtonString": { + "type": "string" + }, + "initialCheckboxValue": { + "type": "boolean" + } + }, + "required": [ + "m-allowed", + "message", + "explanation", + "defaultButton", + "okButtonString", + "initialCheckboxValue" + ] + } + }, + "required": [ + "pings", + "accountInfo", + "passwordToken", + "clearToken", + "m-allowed", + "is-cloud-enabled", + "dsPersonId", + "creditDisplay", + "creditBalance", + "freeSongBalance", + "isManagedStudent", + "action", + "subscriptionStatus", + "accountFlags", + "status", + "download-queue-info", + "privacyAcknowledgement", + "dialog" + ] +} \ No newline at end of file diff --git a/src_mac/ipatool-py/reqs/schemas/schema_defs/store_buyproduct_req.json b/src_mac/ipatool-py/reqs/schemas/schema_defs/store_buyproduct_req.json new file mode 100755 index 0000000..5f624e7 --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/schema_defs/store_buyproduct_req.json @@ -0,0 +1,120 @@ +{ + "title": "Store BuyProduct Req", + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "ageCheck": { + "type": "string" + }, + "appExtVrsId": { + "type": "string" + }, + "guid": { + "type": "string" + }, + "hasBeenAuthedForBuy": { + "type": "string" + }, + "isInApp": { + "type": "string" + }, + "kbsync": { + "type": "string" + }, + "sbsync": { + "type": "string" + }, + "afds": { + "type": "string" + }, + "machineName": { + "type": "string" + }, + "mtApp": { + "type": "string" + }, + "mtClientId": { + "type": "string" + }, + "mtEventTime": { + "type": "string" + }, + "mtPageId": { + "type": "string" + }, + "mtPageType": { + "type": "string" + }, + "mtPrevPage": { + "type": "string" + }, + "mtRequestId": { + "type": "string" + }, + "mtTopic": { + "type": "string" + }, + "needDiv": { + "type": "string" + }, + "pg": { + "type": "string" + }, + "price": { + "type": "string" + }, + "pricingParameters": { + "type": "string" + }, + "productType": { + "type": "string" + }, + "salableAdamId": { + "type": "string" + }, + + "hasAskedToFulfillPreorder": { + "type": "string" + }, + "buyWithoutAuthorization": { + "type": "string" + }, + "hasDoneAgeCheck": { + "type": "string" + }, + "hasConfirmedPaymentSheet": { + "type": "string" + }, + "asn": { + "type": "string" + } + }, + "required": [ + "guid", + "kbsync", + "price", + "pricingParameters", + "productType", + "salableAdamId", + "appExtVrsId" + ], + "optional": [ + "ageCheck", + "hasBeenAuthedForBuy", + "hasConfirmedPaymentSheet", + "asn", + "isInApp", + + "machineName", + "mtApp", + "mtClientId", + "mtEventTime", + "mtPageId", + "mtPageType", + "mtPrevPage", + "mtRequestId", + "mtTopic", + "needDiv", + "pg" + ] +} \ No newline at end of file diff --git a/src_mac/ipatool-py/reqs/schemas/schema_defs/store_buyproduct_resp.json b/src_mac/ipatool-py/reqs/schemas/schema_defs/store_buyproduct_resp.json new file mode 100755 index 0000000..6c50940 --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/schema_defs/store_buyproduct_resp.json @@ -0,0 +1,732 @@ +{ + "title": "Store BuyProduct Resp", + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "pings": { + "type": "array", + "items": { + "type": ["number","string","boolean","object","array", "null"] + } + }, + "jingleDocType": { + "type": "string" + }, + "jingleAction": { + "type": "string" + }, + "status": { + "type": "integer" + }, + "dsPersonId": { + "type": "string" + }, + "creditDisplay": { + "type": "string" + }, + "creditBalance": { + "type": "string" + }, + "freeSongBalance": { + "type": "string" + }, + "creditDisplayInternal": { + "type": "string" + }, + "authorized": { + "type": "boolean" + }, + "download-queue-item-count": { + "type": "integer" + }, + "songList": { + "type": "array", + "items": { + "type": "object", + "properties": { + "songId": { + "type": "integer" + }, + "URL": { + "type": "string" + }, + "downloadKey": { + "type": "string" + }, + "artworkURL": { + "type": "string" + }, + "artwork-urls": { + "type": "object", + "properties": { + "image-type": { + "type": "string" + }, + "default": { + "type": "object", + "properties": { + "url": { + "type": "string" + } + }, + "required": [ + "url" + ] + } + }, + "required": [ + "image-type", + "default" + ] + }, + "md5": { + "type": "string" + }, + "chunks": { + "type": "object", + "properties": { + "chunkSize": { + "type": "integer" + }, + "hashes": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "chunkSize", + "hashes" + ] + }, + "isStreamable": { + "type": "boolean" + }, + "uncompressedSize": { + "type": "integer" + }, + "sinfs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "sinf": { + "type": "string" + } + }, + "required": [ + "id", + "sinf" + ] + } + }, + "purchaseDate": { + "type": "string" + }, + "download-id": { + "type": "string" + }, + "is-in-queue": { + "type": "boolean" + }, + "asset-info": { + "type": "object", + "properties": { + "file-size": { + "type": "integer" + }, + "flavor": { + "type": "string" + } + }, + "required": [ + "file-size", + "flavor" + ] + }, + "metadata": { + "type": "object", + "properties": { + "MacUIRequiredDeviceCapabilities": { + "type": "object", + "properties": { + "arm64": { + "type": "boolean" + } + }, + "required": [ + "arm64" + ] + }, + "UIRequiredDeviceCapabilities": { + "type": "object", + "properties": { + "arm64": { + "type": "boolean" + } + }, + "required": [ + "arm64" + ] + }, + "WKRunsIndependentlyOfCompanionApp": { + "type": "boolean" + }, + "WKWatchOnly": { + "type": "boolean" + }, + "appleWatchEnabled": { + "type": "boolean" + }, + "artistId": { + "type": "integer" + }, + "artistName": { + "type": "string" + }, + "bundleDisplayName": { + "type": "string" + }, + "bundleShortVersionString": { + "type": "string" + }, + "bundleVersion": { + "type": "string" + }, + "copyright": { + "type": "string" + }, + "fileExtension": { + "type": "string" + }, + "gameCenterEnabled": { + "type": "boolean" + }, + "gameCenterEverEnabled": { + "type": "boolean" + }, + "genre": { + "type": "string" + }, + "genreId": { + "type": "integer" + }, + "itemId": { + "type": "integer" + }, + "itemName": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "nameTranscriptions": { + "type": "object", + "properties": { + "zh-Hans-CN": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "zh-Hans-CN" + ] + }, + "playlistName": { + "type": "string" + }, + "product-type": { + "type": "string" + }, + "rating": { + "type": "object", + "properties": { + "content": { + "type": "string" + }, + "label": { + "type": "string" + }, + "rank": { + "type": "integer" + }, + "system": { + "type": "string" + } + }, + "required": [ + "content", + "label", + "rank", + "system" + ] + }, + "releaseDate": { + "type": "string" + }, + "requiresRosetta": { + "type": "boolean" + }, + "runsOnAppleSilicon": { + "type": "boolean" + }, + "runsOnIntel": { + "type": "boolean" + }, + "s": { + "type": "integer" + }, + "software-platform": { + "type": "string" + }, + "softwareIcon57x57URL": { + "type": "string" + }, + "softwareIconNeedsShine": { + "type": "boolean" + }, + "softwareSupportedDeviceIds": { + "type": "array", + "items": { + "type": "integer" + } + }, + "softwareVersionBundleId": { + "type": "string" + }, + "softwareVersionExternalIdentifier": { + "type": "integer" + }, + "softwareVersionExternalIdentifiers": { + "type": "array", + "items": { + "type": "integer" + } + }, + "vendorId": { + "type": "integer" + }, + "drmVersionNumber": { + "type": "integer" + }, + "versionRestrictions": { + "type": "integer" + }, + "storeCohort": { + "type": "string" + }, + "hasOrEverHasHadIAP": { + "type": "boolean" + } + }, + "required": [ + "MacUIRequiredDeviceCapabilities", + "UIRequiredDeviceCapabilities", + "WKRunsIndependentlyOfCompanionApp", + "WKWatchOnly", + "appleWatchEnabled", + "artistId", + "artistName", + "bundleDisplayName", + "bundleShortVersionString", + "bundleVersion", + "copyright", + "fileExtension", + "gameCenterEnabled", + "gameCenterEverEnabled", + "genre", + "genreId", + "itemId", + "itemName", + "kind", + "nameTranscriptions", + "playlistName", + "product-type", + "rating", + "releaseDate", + "requiresRosetta", + "runsOnAppleSilicon", + "runsOnIntel", + "s", + "software-platform", + "softwareIcon57x57URL", + "softwareIconNeedsShine", + "softwareSupportedDeviceIds", + "softwareVersionBundleId", + "softwareVersionExternalIdentifier", + "softwareVersionExternalIdentifiers", + "vendorId", + "drmVersionNumber", + "versionRestrictions", + "storeCohort", + "hasOrEverHasHadIAP" + ] + } + }, + "required": [ + "songId", + "URL", + "downloadKey", + "artworkURL", + "artwork-urls", + "md5", + "chunks", + "isStreamable", + "uncompressedSize", + "sinfs", + "purchaseDate", + "download-id", + "is-in-queue", + "asset-info", + "metadata" + ] + } + }, + "download-queue-info": { + "type": "object", + "properties": { + "download-queue-item-count": { + "type": "integer" + }, + "dsid": { + "type": "integer" + }, + "is-auto-download-machine": { + "type": "boolean" + } + }, + "required": [ + "download-queue-item-count", + "dsid", + "is-auto-download-machine" + ] + }, + "metrics": { + "type": "object", + "properties": { + "itemIds": { + "type": "array", + "items": { + "type": "integer" + } + }, + "price": { + "type": "integer" + }, + "priceType": { + "type": "string" + }, + "productTypes": { + "type": "array", + "items": { + "type": "string" + } + }, + "mtApp": { + "type": "string" + }, + "mtClientId": { + "type": "string" + }, + "mtEventTime": { + "type": "string" + }, + "mtPageId": { + "type": "string" + }, + "mtPageType": { + "type": "string" + }, + "mtPrevPage": { + "type": "string" + }, + "mtRequestId": { + "type": "string" + }, + "mtTopic": { + "type": "string" + }, + "currency": { + "type": "string" + }, + "exchangeRateToUSD": { + "type": "number" + }, + "commerceEvent_purchase_priceType": { + "type": "string" + }, + "commerceEvent_storeFrontId": { + "type": "string" + }, + "commerceEvent_result_resultType": { + "type": "integer" + }, + "commerceEvent_flowType": { + "type": "integer" + }, + "commerceEvent_flowStep": { + "type": "integer" + }, + + "dialogId": { + "type": "string" + }, + "message": { + "type": "string" + }, + "messageCode": { + "type": "string" + }, + "options": { + "type": "array", + "items": { + "type": "string" + } + }, + "actionUrl": { + "type": "string" + }, + "asnState": { + "type": "integer" + }, + "eventType": { + "type": "string" + } + }, + "required": [ + "mtApp", + "mtClientId", + "mtEventTime", + "mtPageId", + "mtPageType", + "mtPrevPage", + "mtRequestId", + "mtTopic" + ], + "optional": [ + "itemIds", + "price", + "priceType", + "productTypes", + "currency", + "exchangeRateToUSD", + "commerceEvent_purchase_priceType", + "commerceEvent_storeFrontId", + "commerceEvent_result_resultType", + "commerceEvent_flowType", + "commerceEvent_flowStep", + + "dialogId", + "message", + "messageCode", + "options", + "actionUrl", + "asnState", + "eventType" + ] + }, + "duAnonymousPings": { + "type": "array", + "items": { + "type": "string" + } + }, + "subscriptionStatus": { + "type": "object", + "properties": { + "music": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "reason": { + "type": "string" + }, + "isAdmin": { + "type": "boolean" + }, + "isNotEligibleForFreeTrial": { + "type": "boolean" + } + }, + "required": [ + "status", + "reason", + "isAdmin", + "isNotEligibleForFreeTrial" + ] + }, + "terms": { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "latestTerms": { + "type": "integer" + }, + "agreedToTerms": { + "type": "integer" + }, + "source": { + "type": "string" + } + }, + "required": [ + "type", + "latestTerms", + "agreedToTerms", + "source" + ] + } + }, + "account": { + "type": "object", + "properties": { + "isMinor": { + "type": "boolean" + }, + "suspectUnderage": { + "type": "boolean" + } + }, + "required": [ + "isMinor", + "suspectUnderage" + ] + }, + "family": { + "type": "object", + "properties": { + "hasFamily": { + "type": "boolean" + } + }, + "required": [ + "hasFamily" + ] + } + }, + "required": [ + "music", + "terms", + "account", + "family" + ] + }, + "cancel-purchase-batch": { + "type": "boolean" + }, + "failureType": { + "type": "string" + }, + "customerMessage": { + "type": "string" + }, + "m-allowed": { + "type": "boolean" + }, + "dialog": { + "type": "object", + "properties": { + "kind": { + "type": "string" + }, + "m-allowed": { + "type": "boolean" + }, + "use-keychain": { + "type": "boolean" + }, + "isFree": { + "type": "boolean" + }, + "message": { + "type": "string" + }, + "explanation": { + "type": "string" + }, + "defaultButton": { + "type": "string" + }, + "okButtonString": { + "type": "string" + }, + "okButtonAction": { + "type": "object", + "properties": { + "kind": { + "type": "string" + }, + "buyParams": { + "type": "string" + }, + "itemName": { + "type": "string" + } + }, + "required": [ + "kind", + "buyParams", + "itemName" + ] + }, + "cancelButtonString": { + "type": "string" + }, + "initialCheckboxValue": { + "type": "boolean" + } + }, + "required": [ + "kind", + "m-allowed", + "use-keychain", + "isFree", + "message", + "explanation", + "defaultButton", + "okButtonString", + "okButtonAction", + "cancelButtonString", + "initialCheckboxValue" + ] + } + }, + "required": [ + "pings", + "metrics" + ], + "optional": [ + "jingleDocType", + "jingleAction", + "status", + "dsPersonId", + "creditDisplay", + "creditBalance", + "freeSongBalance", + "creditDisplayInternal", + "authorized", + "download-queue-item-count", + "songList", + "download-queue-info", + "duAnonymousPings", + "subscriptionStatus", + + "failureType", + "customerMessage", + "m-allowed", + "dialog", + "cancel-purchase-batch" + ] +} \ No newline at end of file diff --git a/src_mac/ipatool-py/reqs/schemas/schema_defs/store_download_req.json b/src_mac/ipatool-py/reqs/schemas/schema_defs/store_download_req.json new file mode 100755 index 0000000..c687aa0 --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/schema_defs/store_download_req.json @@ -0,0 +1,24 @@ +{ + "title": "Store Download Req", + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "creditDisplay": { + "type": "string" + }, + "guid": { + "type": "string" + }, + "salableAdamId": { + "type": "string" + }, + "appExtVrsId": { + "type": "string" + } + }, + "required": [ + "creditDisplay", + "guid", + "salableAdamId" + ] +} \ No newline at end of file diff --git a/src_mac/ipatool-py/reqs/schemas/schema_defs/store_download_resp.json b/src_mac/ipatool-py/reqs/schemas/schema_defs/store_download_resp.json new file mode 100755 index 0000000..243b57a --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/schema_defs/store_download_resp.json @@ -0,0 +1,497 @@ +{ + "title": "Store Download Resp", + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "pings": { + "type": "array", + "items": { + "type": ["number","string","boolean","object","array", "null"] + } + }, + "cancel-purchase-batch": { + "type": "boolean" + }, + "customerMessage": { + "type": "string" + }, + "failureType": { + "type": "string" + }, + "jingleDocType": { + "type": "string" + }, + "jingleAction": { + "type": "string" + }, + "status": { + "type": "integer" + }, + "dsPersonId": { + "type": "string" + }, + "creditDisplay": { + "type": "string" + }, + "creditBalance": { + "type": "string" + }, + "freeSongBalance": { + "type": "string" + }, + "authorized": { + "type": "boolean" + }, + "download-queue-item-count": { + "type": "integer" + }, + "songList": { + "type": "array", + "items": { + "type": "object", + "properties": { + "songId": { + "type": "integer" + }, + "URL": { + "type": "string" + }, + "downloadKey": { + "type": "string" + }, + "artworkURL": { + "type": "string" + }, + "artwork-urls": { + "type": "object", + "properties": { + "image-type": { + "type": "string" + }, + "default": { + "type": "object", + "properties": { + "url": { + "type": "string" + } + }, + "required": [ + "url" + ] + } + }, + "required": [ + "image-type", + "default" + ] + }, + "md5": { + "type": "string" + }, + "chunks": { + "type": "object", + "properties": { + "chunkSize": { + "type": "integer" + }, + "hashes": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "chunkSize", + "hashes" + ] + }, + "isStreamable": { + "type": "boolean" + }, + "uncompressedSize": { + "type": "string" + }, + "sinfs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "sinf": { + "type": "string" + } + }, + "required": [ + "id", + "sinf" + ] + } + }, + "purchaseDate": { + "type": "string" + }, + "download-id": { + "type": "string" + }, + "is-in-queue": { + "type": "boolean" + }, + "asset-info": { + "type": "object", + "properties": { + "file-size": { + "type": "integer" + }, + "flavor": { + "type": "string" + } + }, + "required": [ + "file-size", + "flavor" + ] + }, + "metadata": { + "type": "object", + "properties": { + "MacUIRequiredDeviceCapabilities": { + "type": "object", + "properties": { + "arm64": { + "type": "boolean" + }, + "gamekit": { + "type": "boolean" + }, + "metal": { + "type": "boolean" + } + }, + "required": [ + "arm64", + "gamekit", + "metal" + ] + }, + "UIRequiredDeviceCapabilities": { + "type": "object", + "properties": { + "arm64": { + "type": "boolean" + }, + "gamekit": { + "type": "boolean" + }, + "metal": { + "type": "boolean" + } + }, + "required": [ + "arm64", + "gamekit", + "metal" + ] + }, + "artistId": { + "type": "integer" + }, + "artistName": { + "type": "string" + }, + "bundleDisplayName": { + "type": "string" + }, + "bundleShortVersionString": { + "type": "string" + }, + "bundleVersion": { + "type": "string" + }, + "copyright": { + "type": "string" + }, + "fileExtension": { + "type": "string" + }, + "gameCenterEnabled": { + "type": "boolean" + }, + "gameCenterEverEnabled": { + "type": "boolean" + }, + "genre": { + "type": "string" + }, + "genreId": { + "type": "integer" + }, + "itemId": { + "type": "integer" + }, + "itemName": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "playlistName": { + "type": "string" + }, + "product-type": { + "type": "string" + }, + "rating": { + "type": "object", + "properties": { + "content": { + "type": "string" + }, + "label": { + "type": "string" + }, + "rank": { + "type": "integer" + }, + "system": { + "type": "string" + } + }, + "required": [ + "content", + "label", + "rank", + "system" + ] + }, + "releaseDate": { + "type": "string" + }, + "requiresRosetta": { + "type": "boolean" + }, + "runsOnAppleSilicon": { + "type": "boolean" + }, + "runsOnIntel": { + "type": "boolean" + }, + "s": { + "type": "integer" + }, + "software-platform": { + "type": "string" + }, + "softwareIcon57x57URL": { + "type": "string" + }, + "softwareIconNeedsShine": { + "type": "boolean" + }, + "softwareSupportedDeviceIds": { + "type": "array", + "items": { + "type": "integer" + } + }, + "softwareVersionBundleId": { + "type": "string" + }, + "softwareVersionExternalIdentifier": { + "type": "integer" + }, + "softwareVersionExternalIdentifiers": { + "type": "array", + "items": { + "type": "integer" + } + }, + "subgenres": { + "type": "array", + "items": { + "type": "object", + "properties": { + "genre": { + "type": "string" + }, + "genreId": { + "type": "integer" + } + }, + "required": [ + "genre", + "genreId" + ] + } + }, + "vendorId": { + "type": "integer" + }, + "drmVersionNumber": { + "type": "integer" + }, + "versionRestrictions": { + "type": "integer" + } + }, + "required": [ + "MacUIRequiredDeviceCapabilities", + "UIRequiredDeviceCapabilities", + "artistId", + "artistName", + "bundleDisplayName", + "bundleShortVersionString", + "bundleVersion", + "copyright", + "fileExtension", + "gameCenterEnabled", + "gameCenterEverEnabled", + "genre", + "genreId", + "itemId", + "itemName", + "kind", + "playlistName", + "product-type", + "rating", + "releaseDate", + "requiresRosetta", + "runsOnAppleSilicon", + "runsOnIntel", + "s", + "software-platform", + "softwareIcon57x57URL", + "softwareIconNeedsShine", + "softwareSupportedDeviceIds", + "softwareVersionBundleId", + "softwareVersionExternalIdentifier", + "softwareVersionExternalIdentifiers", + "subgenres", + "vendorId", + "drmVersionNumber", + "versionRestrictions" + ] + } + }, + "required": [ + "songId", + "URL", + "downloadKey", + "artworkURL", + "artwork-urls", + "md5", + "chunks", + "isStreamable", + "uncompressedSize", + "sinfs", + "purchaseDate", + "download-id", + "is-in-queue", + "asset-info", + "metadata" + ] + } + }, + "metrics": { + "type": "object", + "properties": { + "itemIds": { + "type": "array", + "items": { + "type": "integer" + } + }, + "currency": { + "type": "string" + }, + "exchangeRateToUSD": { + "type": "number" + } + }, + "required": [ + "itemIds", + "currency", + "exchangeRateToUSD" + ] + }, + "subscriptionStatus": { + "type": "object", + "properties": { + "terms": { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "latestTerms": { + "type": "integer" + }, + "agreedToTerms": { + "type": "integer" + }, + "source": { + "type": "string" + } + }, + "required": [ + "type", + "latestTerms", + "agreedToTerms", + "source" + ] + } + }, + "account": { + "type": "object", + "properties": { + "isMinor": { + "type": "boolean" + }, + "suspectUnderage": { + "type": "boolean" + } + }, + "required": [ + "isMinor", + "suspectUnderage" + ] + }, + "family": { + "type": "object", + "properties": { + "hasFamily": { + "type": "boolean" + } + }, + "required": [ + "hasFamily" + ] + } + }, + "required": [ + "terms", + "account", + "family" + ] + } + }, + "required": [ + "pings", + "jingleDocType", + "jingleAction", + "status", + "dsPersonId", + "creditDisplay", + "creditBalance", + "freeSongBalance", + "authorized", + "download-queue-item-count", + "songList", + "metrics", + "subscriptionStatus" + ] +} \ No newline at end of file diff --git a/src_mac/ipatool-py/reqs/schemas/schema_examples/itunes_lookup_resp.log b/src_mac/ipatool-py/reqs/schemas/schema_examples/itunes_lookup_resp.log new file mode 100755 index 0000000..135b708 --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/schema_examples/itunes_lookup_resp.log @@ -0,0 +1,13 @@ +{ + "resultCount":1, + "results": [ +{ +"screenshotUrls":["https://is1-ssl.mzstatic.com/image/thumb/Purple123/v4/c7/9d/5a/c79d5ac9-4543-e9d7-acb3-4753704f1488/pr_source.png/392x696bb.png", "https://is5-ssl.mzstatic.com/image/thumb/Purple123/v4/e4/38/3a/e4383af3-d9ed-3d0c-9c80-ca0d413c0f06/pr_source.png/392x696bb.png", "https://is5-ssl.mzstatic.com/image/thumb/Purple123/v4/08/b2/39/08b23995-3c76-3e74-5af4-3edb4914dc4c/pr_source.png/392x696bb.png"], +"ipadScreenshotUrls":["https://is5-ssl.mzstatic.com/image/thumb/Purple113/v4/67/74/39/6774390f-7a12-3d9f-ded7-392b9af90663/pr_source.png/576x768bb.png", "https://is4-ssl.mzstatic.com/image/thumb/Purple123/v4/88/62/85/886285f0-b1c2-ad6b-3ab3-2a5ee70d7c9d/pr_source.png/576x768bb.png", "https://is4-ssl.mzstatic.com/image/thumb/Purple123/v4/29/39/68/29396836-1b94-1561-4bd1-cde929ae5baa/pr_source.png/576x768bb.png"], "appletvScreenshotUrls":[], +"artworkUrl60":"https://is3-ssl.mzstatic.com/image/thumb/Purple123/v4/6b/ed/31/6bed31bd-42d1-5ae9-04fd-a04c865af27d/AppIcon-0-0-1x_U007emarketing-0-0-0-7-0-0-sRGB-0-0-0-GLES2_U002c0-512MB-85-220-0-0.png/60x60bb.jpg", +"artworkUrl512":"https://is3-ssl.mzstatic.com/image/thumb/Purple123/v4/6b/ed/31/6bed31bd-42d1-5ae9-04fd-a04c865af27d/AppIcon-0-0-1x_U007emarketing-0-0-0-7-0-0-sRGB-0-0-0-GLES2_U002c0-512MB-85-220-0-0.png/512x512bb.jpg", +"artworkUrl100":"https://is3-ssl.mzstatic.com/image/thumb/Purple123/v4/6b/ed/31/6bed31bd-42d1-5ae9-04fd-a04c865af27d/AppIcon-0-0-1x_U007emarketing-0-0-0-7-0-0-sRGB-0-0-0-GLES2_U002c0-512MB-85-220-0-0.png/100x100bb.jpg", "artistViewUrl":"https://apps.apple.com/us/developer/potatso-lab-ltd/id1267906737?uo=4", +"supportedDevices":["iPhone5s-iPhone5s", "iPadAir-iPadAir", "iPadAirCellular-iPadAirCellular", "iPadMiniRetina-iPadMiniRetina", "iPadMiniRetinaCellular-iPadMiniRetinaCellular", "iPhone6-iPhone6", "iPhone6Plus-iPhone6Plus", "iPadAir2-iPadAir2", "iPadAir2Cellular-iPadAir2Cellular", "iPadMini3-iPadMini3", "iPadMini3Cellular-iPadMini3Cellular", "iPodTouchSixthGen-iPodTouchSixthGen", "iPhone6s-iPhone6s", "iPhone6sPlus-iPhone6sPlus", "iPadMini4-iPadMini4", "iPadMini4Cellular-iPadMini4Cellular", "iPadPro-iPadPro", "iPadProCellular-iPadProCellular", "iPadPro97-iPadPro97", "iPadPro97Cellular-iPadPro97Cellular", "iPhoneSE-iPhoneSE", "iPhone7-iPhone7", "iPhone7Plus-iPhone7Plus", "iPad611-iPad611", "iPad612-iPad612", "iPad71-iPad71", "iPad72-iPad72", "iPad73-iPad73", "iPad74-iPad74", "iPhone8-iPhone8", "iPhone8Plus-iPhone8Plus", "iPhoneX-iPhoneX", "iPad75-iPad75", "iPad76-iPad76", "iPhoneXS-iPhoneXS", "iPhoneXSMax-iPhoneXSMax", "iPhoneXR-iPhoneXR", "iPad812-iPad812", "iPad834-iPad834", "iPad856-iPad856", "iPad878-iPad878", "iPadMini5-iPadMini5", "iPadMini5Cellular-iPadMini5Cellular", "iPadAir3-iPadAir3", "iPadAir3Cellular-iPadAir3Cellular", "iPodTouchSeventhGen-iPodTouchSeventhGen", "iPhone11-iPhone11", "iPhone11Pro-iPhone11Pro", "iPadSeventhGen-iPadSeventhGen", "iPadSeventhGenCellular-iPadSeventhGenCellular", "iPhone11ProMax-iPhone11ProMax", "iPhoneSESecondGen-iPhoneSESecondGen", "iPadProSecondGen-iPadProSecondGen", "iPadProSecondGenCellular-iPadProSecondGenCellular", "iPadProFourthGen-iPadProFourthGen", "iPadProFourthGenCellular-iPadProFourthGenCellular", "iPhone12Mini-iPhone12Mini", "iPhone12-iPhone12", "iPhone12Pro-iPhone12Pro", "iPhone12ProMax-iPhone12ProMax", "iPadAir4-iPadAir4", "iPadAir4Cellular-iPadAir4Cellular", "iPadEighthGen-iPadEighthGen", "iPadEighthGenCellular-iPadEighthGenCellular", "iPadProThirdGen-iPadProThirdGen", "iPadProThirdGenCellular-iPadProThirdGenCellular", "iPadProFifthGen-iPadProFifthGen", "iPadProFifthGenCellular-iPadProFifthGenCellular", "iPhone13Pro-iPhone13Pro", "iPhone13ProMax-iPhone13ProMax", "iPhone13Mini-iPhone13Mini", "iPhone13-iPhone13", "iPadMiniSixthGen-iPadMiniSixthGen", "iPadMiniSixthGenCellular-iPadMiniSixthGenCellular", "iPadNinthGen-iPadNinthGen", "iPadNinthGenCellular-iPadNinthGenCellular", "iPhoneSEThirdGen-iPhoneSEThirdGen", "iPadAirFifthGen-iPadAirFifthGen", "iPadAirFifthGenCellular-iPadAirFifthGenCellular"], "features":["iosUniversal"], "advisories":[], "isGameCenterEnabled":false, "kind":"software", "minimumOsVersion":"13.0", "trackCensoredName":"Potatso Lite", "languageCodesISO2A":["EN", "ZH"], "fileSizeBytes":"18907136", "sellerUrl":"https://potatso.com/en", "formattedPrice":"Free", "contentAdvisoryRating":"4+", "averageUserRatingForCurrentVersion":4.595620000000000260342858382500708103179931640625, "userRatingCountForCurrentVersion":2923, "averageUserRating":4.595620000000000260342858382500708103179931640625, "trackViewUrl":"https://apps.apple.com/us/app/potatso-lite/id1239860606?uo=4", "trackContentRating":"4+", "trackId":1239860606, "trackName":"Potatso Lite", "bundleId":"com.touchingapp.potatsolite", "primaryGenreName":"Utilities", "releaseDate":"2017-06-01T02:34:35Z", "genreIds":["6002", "6007"], "isVppDeviceBasedLicensingEnabled":true, "sellerName":"Potatso Lab LTD", "currentVersionReleaseDate":"2019-12-16T23:27:27Z", +"releaseNotes":"With this update, we're bringing you some exciting new features and changes. \n\n=====================\n===== What's New =====\n=====================\n\n• The app will support iOS 13+ from now on.\n• We're introducing the brand new logo with clarity and simplicity.\n• We've redeisnged the whole UI to improve your using experience.\n• Some other internal performance improvements and bug fixes.", "primaryGenreId":6002, "currency":"USD", "version":"2.5.0", "wrapperType":"software", "artistId":1267906737, "artistName":"Potatso Lab LTD", "genres":["Utilities", "Productivity"], "price":0.00, +"description":"Potatso Lite is a powerful network tool which empowers your phone to have fully customized network environment. It's friendly for both beginners and power users. \n\nPotatso now supports Shadowsocks, ShadowsocksR, HTTP and Socks5 proxies. You can either setup one by yourself or buy from any proxy providers.\n\nEmbedded smart rouing feature for Chinese users is super helpful which can cost less data in proxy servers and speed up domestic network traffic.\n\n=== Features ===\n- Custom proxy supports Shadowsocks, ShadowsocksR, HTTP and Socks5 \n- Run in the background sustainably without interrupting you\n- Both cellular and Wi-Fi are supported\n- Custom DNS support\n- Smart Routing for Chinese users \n\n=== Privacy ===\nWe respect your privacy so NO confidential data will be uploaded or shared with third parties\n\n=== Feedback ===\nPlease contact on hi@potatso.com", "userRatingCount":2923}] +} \ No newline at end of file diff --git a/src_mac/ipatool-py/reqs/schemas/schema_examples/store_buyproduct_req.log b/src_mac/ipatool-py/reqs/schemas/schema_examples/store_buyproduct_req.log new file mode 100755 index 0000000..24487c8 --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/schema_examples/store_buyproduct_req.log @@ -0,0 +1,107 @@ + + + + appExtVrsId + 848463733 + guid + 22330C8C.C2E39C5C.06C40B91.D0990F95.9A890F9D.AB7F7EB4.56507025 + kbsync + + AAQAA5nBc3Q7ETi+TD1x8AM4wbw9sqWglXBaXwuIrlMR9OnAPY89zaoTvbe6PneuS1x1 + 31NxVIqrAsIZLmxy5be8dQtq8je/rtYTRlxduU9NwW4DBcplBx6vs9qhS3Y8B45Zz4T5 + dkmDG4UnS7xnAPwew7jEX/uY38zZhtKu4IN+sl/Whvyh2SkZg/5vGCtjav17CGbP8ZWo + Ci3FhEqAByOL0g6zhPdTHyqF84Apg9fh395tGpzzAWB8mYsRQXJcUHH1cuJjO/qMTkZ4 + ZxIJqfMaDJpS20nFq+/Bfg9FvC/83AOPnDfXZTsol3PFKqQ6sLgz6dKIho4Qd2UPABnj + kBx4TFPeYBlm2T6GKfi8tr+rDhsMrbNczpnaUS+3cesIOvDsE3YCX4isOmMtg5yrJ5pi + 2GHuofHD2I7Dj6fOh79I7F5OZb71PUvbeABjxvS5b57LGNICSBc/GJ0CEja27kpYals+ + bgYG0rVm+vqlAHwRpka5jzeK8DLrvTr22vtBLv62LpTVpVVglr5nbk99BcXG5gA= + + machineName + DESKTOP-697LVJS + mtApp + com.apple.iTunes + mtClientId + 3z21abvCzFDuz5CYz9bdz19maFVKge + mtEventTime + 1652006678827 + mtPageId + ccfce0ef-4ac8-4d5a-8e5f-79876ac474a4 + mtPageType + Search + mtPrevPage + Purchases + mtRequestId + 3z21abvCzFDuz5CYz9bdz19maFVKgezL2X64FFVz1MGG + mtTopic + xp_its_main + needDiv + 0 + pg + default + price + 0 + pricingParameters + STDQ + productType + C + salableAdamId + 444934666 + + + + + + + ageCheck + true + appExtVrsId + 848463733 + guid + 22330C8C.C2E39C5C.06C40B91.D0990F95.9A890F9D.AB7F7EB4.56507025 + hasBeenAuthedForBuy + true + isInApp + false + kbsync + + AAQAA1c+HfGD4vNLZJYBMpBucSo1bxeaeTEZ3FGUKLq0skmzTxVik6IGoQMGaP6OWsJU + lBoDb3hxaacD57bkiAgRXc/vr21/CipX55hKLoTE53yah3DwBR9tS1cG7oaHFLIh1Vmn + RV7G9LJCQqwSAbr4ugEIVmLULkqaHDfTm8VNDXxYej1p8ghKggMcBT0se5cpDqpVn/bE + qehnOl6QsupUNjjLzDm58bmERm/AjGJVBHQveG+4Y+Y4e1eUO6QQcntmypjmSLDqhI60 + 31rCV3zwTTZrHmmXEwsZiGgYlSVHR3ne+O9BE+LIPiQxDwIMvjfV6SrzoOUOLlOKvBsk + kI29+6H0QNyMUXojWPQf7bfr+9NBTMgJoDNJd5hEGHqiSKnp9V1ALU8S8QwcYzi3ZDPu + A36lMtgMOFEnYibnGnP5S8i2t43ZSBglExE9LGTGO0/IEWX9gEhKjvMDuIwMt9zdtpye + CXO8siqHY4MtmLlfwZZc/480ZSHfRF8ZQHBa0J0/pgByNQiNe9KMihz+QN7cQI4= + + machineName + DESKTOP-697LVJS + mtApp + com.apple.iTunes + mtClientId + 3z21abvCzFDuz5CYz9bdz19maFVKge + mtEventTime + 1652006678827 + mtPageId + ccfce0ef-4ac8-4d5a-8e5f-79876ac474a4 + mtPageType + Search + mtPrevPage + Purchases + mtRequestId + 3z21abvCzFDuz5CYz9bdz19maFVKgezL2X64FFVz1MGG + mtTopic + xp_its_main + needDiv + 0 + pg + default + price + 0 + pricingParameters + STDQ + productType + C + salableAdamId + 444934666 + + \ No newline at end of file diff --git a/src_mac/ipatool-py/reqs/schemas/schema_examples/store_buyproduct_resp.log b/src_mac/ipatool-py/reqs/schemas/schema_examples/store_buyproduct_resp.log new file mode 100755 index 0000000..0cf06bd --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/schema_examples/store_buyproduct_resp.log @@ -0,0 +1,561 @@ + + + +pings +https://xp.apple.com/report/2/xp_its_main?app=com.apple.iTunes&code=MZCommerce.ASN.ExpiredPasswordToken&buttons=%E8%8E%B7%E5%8F%96%3A%E5%8F%96%E6%B6%88&baseVersion=1&dsId=16916646015&eventVersion=1&storeFrontHeader=143465-19%2C32&eventTime=1652006682067&eventType=dialog&message=%E9%9C%80%E8%A6%81%E7%99%BB%E5%BD%95 + +metrics + + dialogIdMZCommerce.ASN.ExpiredPasswordToken + message需要登录 + messageCode2072 + options + + Get + Cancel + + actionUrlp36-buy.itunes.apple.com/WebObjects/MZBuy.woa/wa/buyProduct + asnState2 + mtAppcom.apple.iTunes + mtClientId3z21abvCzFDuz5CYz9bdz19maFVKge + mtEventTime2022-05-08 10:44:38 Etc/GMT + mtPageIdccfce0ef-4ac8-4d5a-8e5f-79876ac474a4 + mtPageTypeSearch + mtPrevPagePurchases + mtRequestId3z21abvCzFDuz5CYz9bdz19maFVKgezL2X64FFVz1MGG + mtTopicxp_its_main + eventTypedialog + +failureType2072 +customerMessage需要登录 +m-allowed +dialog +kindauthorization +m-allowed +use-keychain +isFree +message需要登录 +explanation如果您有 Apple ID 和密码,请在此处输入。例如,如果您使用过 iTunes Store 或 iCloud,那么您已有 Apple ID。 +defaultButtonok +okButtonString获取 +okButtonActionkindBuy +buyParamsmtEventTime=1652006678827&salableAdamId=444934666&mtRequestId=3z21abvCzFDuz5CYz9bdz19maFVKgezL2X64FFVz1MGG&appExtVrsId=848463733&mtTopic=xp_its_main&guid=22330C8C.C2E39C5C.06C40B91.D0990F95.9A890F9D.AB7F7EB4.56507025&hasBeenAuthedForBuy=true&isInApp=false&price=0&mtClientId=3z21abvCzFDuz5CYz9bdz19maFVKge&productType=C&mtPageType=Search&mtPageId=ccfce0ef-4ac8-4d5a-8e5f-79876ac474a4&machineName=DESKTOP-697LVJS&ageCheck=true&pg=default&mtApp=com.apple.iTunes&needDiv=0&mtPrevPage=Purchases&pricingParameters=STDQ +itemNameQQ + +cancelButtonString取消 +initialCheckboxValue +cancel-purchase-batch + + + + + + +pings + +jingleDocTypepurchaseSuccess +jingleActionpurchaseProduct +status0 + +dsPersonId10964418715 +creditDisplay +creditBalance1311811 +freeSongBalance1311811 + +authorizeddownload-queue-item-count0 +songList + + +metrics + + + itemIds + + 580311103 + + price0.00 + priceTypeSTDQ + productTypes + + C + + currencyJPY + exchangeRateToUSD0.0076722418 + commerceEvent_purchase_priceTypeSTDQ + commerceEvent_storeFrontId143462 + commerceEvent_result_resultType0 + commerceEvent_flowType4 + commerceEvent_flowStep6 + + + duAnonymousPings + + https://xp.apple.com/report/2/xp_app_buy?clientId=0&sf=143462&adamId=580311103 + +subscriptionStatus + +terms + + +typeStore +latestTerms28 +agreedToTerms31 +sourceaccount + + +account + +isMinor +suspectUnderage + +family + +hasFamily + + + + + + + + + +pings + +jingleDocTypepurchaseSuccess +jingleActionpurchaseProduct +status0 + +dsPersonId16916646015 +creditDisplay +creditBalance1311811 +freeSongBalance1311811 +creditDisplayInternalÂ¥0.00+0+0+0+0+0 + +authorized + +download-queue-item-count1 +songList + + +songId444934666 +URLhttps://iosapps.itunes.apple.com/itunes-assets/Purple112/v4/8c/5d/34/8c5d343a-2132-8690-c6b1-866ec2f6b2f6/extDirwkazoqouvdywwgjk.lc.14519290919268642.5LAVFF7SAES2W.signed.dpkg.ipa?accessKey=1652201151_1282442801256894451_c%2FtMyevC%2FbCtPTcx3kpjPzNcDfSmgpz1CnzuNFgB%2F1n13VEU1IYDwlq1Xie8WXNHq4U4t341RRlyT3J1OI1Doy1%2FKOG8Pk4u38Kn30NHbCnmgCRC2r9lGlND9ZjU7AxGCQeVb5iHc74Vf5i7Exbg3hq5UfUddWq%2BBe7s3VEyvOX9Rikq0Hzj4OkYUkklrks95yuvrEhXjMFYO8YpQAr0tCjKoyU2rvjS%2BwnPYk5U0Hy6DnusEJ3JmJpJKC6EiLvb +downloadKeyartworkURLhttps://is5-ssl.mzstatic.com/image/thumb/Purple112/v4/b9/ac/4e/b9ac4ef3-0152-fa92-872f-fe773d799117/AppIcon-1-0-0-1x_U007emarketing-0-0-0-7-0-0-sRGB-0-0-0-GLES2_U002c0-512MB-85-220-0-0.png/2000x2000bb.jpgartwork-urls + +image-typedownload-queue-item +default + +url +https://is4-ssl.mzstatic.com/image/thumb/Purple112/v4/b9/ac/4e/b9ac4ef3-0152-fa92-872f-fe773d799117/AppIcon-1-0-0-1x_U007emarketing-0-0-0-7-0-0-sRGB-0-0-0-GLES2_U002c0-512MB-85-220-0-0.png/57x57bb.jpg + + +md5cb3a13a60ac4c9f507b0fefa351e0351chunks + +chunkSize10485760 +hashes + +a9c3b17b7fd5ce1380580c6f063c469b +8dfa7efed3cccca58987ec5fb5aad752 +c636e4bfcdc17f5ce23a8ef104a44fa3 +90911e7b4d63bf8d4fc1c0bb2756211b +0c7ae0bfa13df1a3cb25d18eccf79083 +4edbba71a6baabeba209cbe495144017 +2b915fa08b532ef007787f3cf9ed68e6 +e8ae486763cd40c730a6f2008bb212df +a91b20af08349a115d318a3c1a9ac69c +001a0a9e6f0f779365fd1a9e08993afa +d9c965a523b445f662aac8eb49fa271e +22f61327c32a4569a4d81f29ae93f238 +3caf910c1da7640a89a51c2ae33e8a3b +70fcd6e5517144b1298848bd964f4dcc +9fb4924aed5006d2c7037be6532d1652 +fb341fcaaf6027182f885628e15542f6 +a0999c33fa684fa21cf2d8c8a4d45e27 +28025c9522f1dc05360e36a9e6da508b +ea980ee5fae29238778cdd16a1f0a2fa +699c2c8bcd5b4b9353bba25a58bb45f8 +10423be39910d01b9e763cc1514fef05 +3da83694d61846e91a0a21981e88652a +937391e158c46e385bf1ebd2f17501aa +18a12b305b3a0086d76d4f9c72764a00 +c19f2b5c1eeb909db77b5d715e023511 +80552d4ed44472cf0f307bc6e6e4180c +9af9bebfb73a15084186032efd64f95b +bdc8305c863637d6031c079f3438b2b2 +406fff31a2d714ffa1eb7c417232c478 +f29550bd0e718ca8588d13654a14e669 +ea916c4a8e8f772610bd4de2549ec891 +9ff8f440fb8260ffe7e39e17215e8e9f +b596fe96037d6e0e52401676b87fc6c0 +1be6f6b3141c80d2b3ad952db9e92ebb +4a9061c50a209184f7d4a54f80ce61ef +e6505a456ca2273700dcad1dead1f625 +9ac28b8e7dd43be5fd309f16403afef8 +5088792cdb4928532714a7023df1275d +c0b0d04fd38919c8688c5e793b33d5e4 +a87331d5e314e6708f6cc67075e36c56 +63ea3257f99d04b44730924cb4a0d553 +b3d953d072a3b0e8e264c16d96cebeaf +5eff58a53e7f7e87f57fcb038a4ad0a4 +e37467e9f2c7d336c3742b63ee70b4ab +abfcdd0ba248ee9c5bc1b4bf8ab03c15 +7c4d4ccfcaaef4708f3d1b0fce994294 +927273c03da6f0fcdc674b40224c0a6d +648761edcf4c3d69e147b3671abee7a8 +146e363283ed83bfd72a8c4d6b8fa7ac +69c8e188357d463d00bd7f8134786b1c +babbb9b2f0c3d31a4d9e0e0d77852f5e +ae46925c45e689783c38f065a9d1e7ea +c7f4967cb830f008417c02009ae2196a +9b8f17524eb05a512c26bb9e2b89220b +11cdc44dd07fe5d9fa3eaba0a179704c +d0f17891f1c141e39cfcacfb58c1bb3c +3273d004f5971ebee5625868d4978f69 +0aa895b7d15ad0760156b3062fb6deeb +7b27b6e73b0731b307399aa4da837df9 + + +isStreamable +uncompressedSize795979776 +sinfs id 0 sinf AAAEIHNpbmYAAAAMZnJtYWdhbWUAAAAUc2NobQAAAABpdHVuAAAAAAAAA3BzY2hpAAAADHVzZXLwT4h/AAAADGNyZHTenU/fAAAADGFzZHQAAAAAAAAADGtleSAAAAACAAAAGGl2aXaD6ySnLt5l3Pdp75fJ0mjxAAAAWHJpZ2h2ZUlEAAEOnHBsYXQAAAABYXZlcgEBAQB0cmFu3p1P33NpbmcAAAAAc29uZxqFKgp0b29sUDYwNG1lZGkAAACAbW9kZQAAIABoaTMyAAAAAwAAAQhuYW1l5q63IOWmueS7jQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcBwcml2eDOeoQvqIT8I9Y9+tU7xixDGAGJI8TvGWPhI2r7kjf9vKy/JunWkBOLN7Ft3eFaFidNSVs3VTlvYSulf3VT0QAc0+3/pFznoHsNC5pMpQ6y0HdBW+8nG+JbiLjeTU3Nj2akunI45wVAiE2IWr1mERJwFG5CavbGOvHM9JBxkHaczFWUUm60zUHuMiBGZiZVDbVI4Oilxdn0vRb3c2P0zDrhOyxez9B7ppEMzJpFkDa2ieFSE0peNxsx8xi+BLWqQ88IZiCpCrLma3P5Wj40hb0nXclQY2t9Zvnw54A2DC/NHEUEDq1T/cZvAi16AdDRB0/GWOTLf7RNf1R8glahArjoD+fddyk9MuVwEN63YqCH/bNh1L7+hpk0Vh2tDGuEy/KDA30kZgF9Z2FED9LAQpCmx1BHUc60NDq++mCImFNiO528OnwirxjZoMWCZWsyCBL+RDTLcNLZOVDwKJcCqP+xLhbbSD8yoQhug/5reFOIUieODiQHGnfVmUmVe9sDuoJmEME3MHMwUHIpGkVfXVE6SPxA2eoN6EReeKwVwbDeLsp/r/dA8jX7BWW9WSjjfAAAAAAAAAAAAAACIc2lnbggl0CkIwRg6tBbdAWQKT2ZlMkYC2bZvWrsyeLzUy+BSYJAs7v2jr1DkRH/xdJbaDjvmkCvS75EUlCXU0oJYT8BydxZzTpJNMALVfwuJNELOkm8sqlCN1/zP1KM3XOeEMu/k6MmtV4nG3zOtLRcKHg5YRz17WcccdTSz251J2Ugn purchaseDate2022-05-08T10:45:51Z +download-id501382282407089488 +is-in-queue + + asset-info + + file-size611092999 + flavor10:purple + +metadata + + MacUIRequiredDeviceCapabilities + + arm64 + + UIRequiredDeviceCapabilities + + arm64 + + WKRunsIndependentlyOfCompanionApp + WKWatchOnly + appleWatchEnabled + artistId292374531 + artistNameTencent Technology (Shenzhen) Company Limited + bundleDisplayNameQQ + bundleShortVersionString8.8.88 + bundleVersion8.8.88.662 + copyrightCopyright © 1998- 2022 Tencent. All Rights Reserved + fileExtension.app + gameCenterEnabled + gameCenterEverEnabled + genre社交 + genreId6005 + itemId444934666 + itemNameQQ + kindsoftware + nameTranscriptions + + zh-Hans-CN + + QQ + + + playlistNameTencent Technology (Shenzhen) Company Limited + product-typeios-app + rating + + content偶尔/轻微的色情内容或裸露 , Advisory.NO.GAMBLING_CONTESTS , 偶尔/轻微的成人或性暗示题材 , Advisory.NO.UNRESTRICTED_WEB_ACCESS and Advisory.NO.TRUE_GAMBLING + label12+ + rank300 + systemitunes-games + + releaseDate2011-06-23T03:33:55Z + requiresRosetta + runsOnAppleSilicon + runsOnIntel + s143465 + software-platformios + softwareIcon57x57URLhttps://is4-ssl.mzstatic.com/image/thumb/Purple112/v4/b9/ac/4e/b9ac4ef3-0152-fa92-872f-fe773d799117/AppIcon-1-0-0-1x_U007emarketing-0-0-0-7-0-0-sRGB-0-0-0-GLES2_U002c0-512MB-85-220-0-0.png/114x114bb.jpg + softwareIconNeedsShine + softwareSupportedDeviceIds + + 2 + 9 + 4 + + softwareVersionBundleIdcom.tencent.mqq + softwareVersionExternalIdentifier848463733 + softwareVersionExternalIdentifiers + + 3843900 + 3876776 + 3941034 + 3973775 + 4070873 + 4135846 + 4321059 + 4492645 + 4917185 + 5632593 + 6232232 + 6860432 + 7792605 + 9642362 + 11556077 + 11818464 + 12638046 + 13422327 + 14959445 + 15410008 + 15765932 + 15854719 + 16122679 + 31562763 + 275882650 + 385122645 + 580102645 + 595393136 + 608133076 + 629072654 + 687502658 + 747082669 + 811253584 + 811445779 + 811179715 + 811445780 + 811590055 + 811669050 + 812133257 + 812375519 + 812625692 + 812972631 + 813031156 + 813192464 + 813298393 + 813463229 + 813961231 + 813962159 + 814174262 + 814318376 + 814527796 + 814531991 + 814639613 + 814754396 + 814882132 + 815144899 + 815147083 + 815188393 + 815573881 + 815574602 + 815607136 + 815810968 + 815897122 + 815938087 + 815938591 + 816130933 + 816210673 + 816305041 + 816356364 + 816843896 + 816912335 + 817028549 + 817235792 + 817473714 + 817549698 + 817788181 + 817933532 + 818110324 + 818431910 + 818825180 + 818979113 + 819096686 + 819416223 + 819489902 + 819842838 + 819893353 + 820113905 + 820199943 + 820442929 + 820548304 + 820595060 + 821268583 + 821341311 + 821500924 + 821954014 + 822037007 + 822096329 + 822279520 + 822523036 + 822895308 + 822957820 + 823194852 + 823309872 + 823713346 + 824097583 + 824171129 + 824301257 + 824389600 + 825024981 + 825145808 + 825307653 + 825347730 + 825611268 + 825729315 + 825895542 + 825933124 + 826313718 + 826632543 + 826837026 + 827460275 + 828106847 + 828385681 + 828600919 + 828666943 + 828716670 + 828897691 + 829301009 + 829496800 + 829679760 + 829821912 + 830133231 + 830530856 + 830742895 + 831337375 + 831405629 + 831472755 + 831824011 + 832139548 + 832542612 + 832827329 + 833393416 + 833855517 + 834104017 + 834138755 + 834768091 + 834880993 + 834939578 + 835135459 + 835524672 + 835716180 + 835976856 + 836375483 + 836825545 + 836945925 + 837334930 + 837735298 + 837835768 + 837881604 + 838238560 + 839235987 + 839700113 + 840003771 + 840041841 + 840921423 + 841227891 + 841968948 + 842099251 + 842166600 + 842303496 + 842463280 + 842670770 + 842892434 + 843105491 + 843416604 + 843638409 + 843881653 + 844115468 + 844170367 + 844356613 + 844638728 + 844786323 + 844986204 + 845375859 + 846332674 + 846748317 + 847332305 + 847747163 + 848017318 + 848463733 + + vendorId69276 + +drmVersionNumber0 +versionRestrictions16843008 +storeCohort10|date=1652005800000&sf=143465&pgtp=Search&pgid=ccfce0ef-4ac8-4d5a-8e5f-79876ac474a4&prpg=Purchases +hasOrEverHasHadIAP + + + + + + download-queue-info + +download-queue-item-count0 +dsid16916646015 +is-auto-download-machine + + + metrics + + + itemIds + + 444934666 + + price0.00 + priceTypeSTDQ + productTypes + + C + + mtAppcom.apple.iTunes + mtClientId3z21abvCzFDuz5CYz9bdz19maFVKge + mtEventTime2022-05-08 10:44:38 Etc/GMT + mtPageIdccfce0ef-4ac8-4d5a-8e5f-79876ac474a4 + mtPageTypeSearch + mtPrevPagePurchases + mtRequestId3z21abvCzFDuz5CYz9bdz19maFVKgezL2X64FFVz1MGG + mtTopicxp_its_main + currencyCNY + exchangeRateToUSD0.1490268546 + commerceEvent_purchase_priceTypeSTDQ + commerceEvent_storeFrontId143465 + commerceEvent_result_resultType0 + commerceEvent_flowType4 + commerceEvent_flowStep6 + + + duAnonymousPings + + https://xp.apple.com/report/2/xp_app_buy?clientId=0&sf=143465&adamId=444934666 + +subscriptionStatus + +music + +statusDisabled +reason +isAdmin +isNotEligibleForFreeTrial + +terms + + +typeStore +latestTerms22 +agreedToTerms22 +sourceaccount + + +account + +isMinor +suspectUnderage + +family + +hasFamily + + + + diff --git a/src_mac/ipatool-py/reqs/schemas/store_authenticate_req.py b/src_mac/ipatool-py/reqs/schemas/store_authenticate_req.py new file mode 100755 index 0000000..29fca3d --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/store_authenticate_req.py @@ -0,0 +1,250 @@ +from reprlib import repr as limitedRepr + + +class StoreAuthenticateReq: + + _types_map = { + "appleId": {"type": str, "subtype": None}, + "attempt": {"type": str, "subtype": None}, + "createSession": {"type": str, "subtype": None}, + "guid": {"type": str, "subtype": None}, + "password": {"type": str, "subtype": None}, + "rmp": {"type": str, "subtype": None}, + "why": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "appleId": { + "required": True, + }, + "attempt": { + "required": True, + }, + "createSession": { + "required": True, + }, + "guid": { + "required": True, + }, + "password": { + "required": True, + }, + "rmp": { + "required": True, + }, + "why": { + "required": True, + }, + } + + def __init__( + self, + appleId: str = None, + attempt: str = None, + createSession: str = None, + guid: str = None, + password: str = None, + rmp: str = None, + why: str = None, + ): + pass + self.__appleId = appleId + self.__attempt = attempt + self.__createSession = createSession + self.__guid = guid + self.__password = password + self.__rmp = rmp + self.__why = why + + def _get_appleId(self): + return self.__appleId + + def _set_appleId(self, value): + if not isinstance(value, str): + raise TypeError("appleId must be str") + + self.__appleId = value + + appleId = property(_get_appleId, _set_appleId) + + def _get_attempt(self): + return self.__attempt + + def _set_attempt(self, value): + if not isinstance(value, str): + raise TypeError("attempt must be str") + + self.__attempt = value + + attempt = property(_get_attempt, _set_attempt) + + def _get_createSession(self): + return self.__createSession + + def _set_createSession(self, value): + if not isinstance(value, str): + raise TypeError("createSession must be str") + + self.__createSession = value + + createSession = property(_get_createSession, _set_createSession) + + def _get_guid(self): + return self.__guid + + def _set_guid(self, value): + if not isinstance(value, str): + raise TypeError("guid must be str") + + self.__guid = value + + guid = property(_get_guid, _set_guid) + + def _get_password(self): + return self.__password + + def _set_password(self, value): + if not isinstance(value, str): + raise TypeError("password must be str") + + self.__password = value + + password = property(_get_password, _set_password) + + def _get_rmp(self): + return self.__rmp + + def _set_rmp(self, value): + if not isinstance(value, str): + raise TypeError("rmp must be str") + + self.__rmp = value + + rmp = property(_get_rmp, _set_rmp) + + def _get_why(self): + return self.__why + + def _set_why(self, value): + if not isinstance(value, str): + raise TypeError("why must be str") + + self.__why = value + + why = property(_get_why, _set_why) + + @staticmethod + def from_dict(d): + v = {} + if "appleId" in d: + v["appleId"] = ( + str.from_dict(d["appleId"]) + if hasattr(str, "from_dict") + else d["appleId"] + ) + if "attempt" in d: + v["attempt"] = ( + str.from_dict(d["attempt"]) + if hasattr(str, "from_dict") + else d["attempt"] + ) + if "createSession" in d: + v["createSession"] = ( + str.from_dict(d["createSession"]) + if hasattr(str, "from_dict") + else d["createSession"] + ) + if "guid" in d: + v["guid"] = ( + str.from_dict(d["guid"]) if hasattr(str, "from_dict") else d["guid"] + ) + if "password" in d: + v["password"] = ( + str.from_dict(d["password"]) + if hasattr(str, "from_dict") + else d["password"] + ) + if "rmp" in d: + v["rmp"] = ( + str.from_dict(d["rmp"]) if hasattr(str, "from_dict") else d["rmp"] + ) + if "why" in d: + v["why"] = ( + str.from_dict(d["why"]) if hasattr(str, "from_dict") else d["why"] + ) + return StoreAuthenticateReq(**v) + + def as_dict(self): + d = {} + if self.__appleId is not None: + d["appleId"] = ( + self.__appleId.as_dict() + if hasattr(self.__appleId, "as_dict") + else self.__appleId + ) + if self.__attempt is not None: + d["attempt"] = ( + self.__attempt.as_dict() + if hasattr(self.__attempt, "as_dict") + else self.__attempt + ) + if self.__createSession is not None: + d["createSession"] = ( + self.__createSession.as_dict() + if hasattr(self.__createSession, "as_dict") + else self.__createSession + ) + if self.__guid is not None: + d["guid"] = ( + self.__guid.as_dict() + if hasattr(self.__guid, "as_dict") + else self.__guid + ) + if self.__password is not None: + d["password"] = ( + self.__password.as_dict() + if hasattr(self.__password, "as_dict") + else self.__password + ) + if self.__rmp is not None: + d["rmp"] = ( + self.__rmp.as_dict() if hasattr(self.__rmp, "as_dict") else self.__rmp + ) + if self.__why is not None: + d["why"] = ( + self.__why.as_dict() if hasattr(self.__why, "as_dict") else self.__why + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__appleId[:20] + if isinstance(self.__appleId, bytes) + else self.__appleId + ), + limitedRepr( + self.__attempt[:20] + if isinstance(self.__attempt, bytes) + else self.__attempt + ), + limitedRepr( + self.__createSession[:20] + if isinstance(self.__createSession, bytes) + else self.__createSession + ), + limitedRepr( + self.__guid[:20] if isinstance(self.__guid, bytes) else self.__guid + ), + limitedRepr( + self.__password[:20] + if isinstance(self.__password, bytes) + else self.__password + ), + limitedRepr( + self.__rmp[:20] if isinstance(self.__rmp, bytes) else self.__rmp + ), + limitedRepr( + self.__why[:20] if isinstance(self.__why, bytes) else self.__why + ), + ) diff --git a/src_mac/ipatool-py/reqs/schemas/store_authenticate_resp.py b/src_mac/ipatool-py/reqs/schemas/store_authenticate_resp.py new file mode 100755 index 0000000..50e3993 --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/store_authenticate_resp.py @@ -0,0 +1,2638 @@ +from reprlib import repr as limitedRepr + + +from typing import List + + +class StoreAuthenticateResp: + class _subscriptionStatus: + class _terms: + + _types_map = { + "type": {"type": str, "subtype": None}, + "latestTerms": {"type": int, "subtype": None}, + "agreedToTerms": {"type": int, "subtype": None}, + "source": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "type": { + "required": True, + }, + "latestTerms": { + "required": True, + }, + "agreedToTerms": { + "required": True, + }, + "source": { + "required": True, + }, + } + + def __init__( + self, + type: str = None, + latestTerms: int = None, + agreedToTerms: int = None, + source: str = None, + ): + pass + self.__type = type + self.__latestTerms = latestTerms + self.__agreedToTerms = agreedToTerms + self.__source = source + + def _get_type(self): + return self.__type + + def _set_type(self, value): + if not isinstance(value, str): + raise TypeError("type must be str") + + self.__type = value + + type = property(_get_type, _set_type) + + def _get_latestTerms(self): + return self.__latestTerms + + def _set_latestTerms(self, value): + if not isinstance(value, int): + raise TypeError("latestTerms must be int") + + self.__latestTerms = value + + latestTerms = property(_get_latestTerms, _set_latestTerms) + + def _get_agreedToTerms(self): + return self.__agreedToTerms + + def _set_agreedToTerms(self, value): + if not isinstance(value, int): + raise TypeError("agreedToTerms must be int") + + self.__agreedToTerms = value + + agreedToTerms = property(_get_agreedToTerms, _set_agreedToTerms) + + def _get_source(self): + return self.__source + + def _set_source(self, value): + if not isinstance(value, str): + raise TypeError("source must be str") + + self.__source = value + + source = property(_get_source, _set_source) + + @staticmethod + def from_dict(d): + v = {} + if "type" in d: + v["type"] = ( + str.from_dict(d["type"]) + if hasattr(str, "from_dict") + else d["type"] + ) + if "latestTerms" in d: + v["latestTerms"] = ( + int.from_dict(d["latestTerms"]) + if hasattr(int, "from_dict") + else d["latestTerms"] + ) + if "agreedToTerms" in d: + v["agreedToTerms"] = ( + int.from_dict(d["agreedToTerms"]) + if hasattr(int, "from_dict") + else d["agreedToTerms"] + ) + if "source" in d: + v["source"] = ( + str.from_dict(d["source"]) + if hasattr(str, "from_dict") + else d["source"] + ) + return StoreAuthenticateResp._subscriptionStatus._terms(**v) + + def as_dict(self): + d = {} + if self.__type is not None: + d["type"] = ( + self.__type.as_dict() + if hasattr(self.__type, "as_dict") + else self.__type + ) + if self.__latestTerms is not None: + d["latestTerms"] = ( + self.__latestTerms.as_dict() + if hasattr(self.__latestTerms, "as_dict") + else self.__latestTerms + ) + if self.__agreedToTerms is not None: + d["agreedToTerms"] = ( + self.__agreedToTerms.as_dict() + if hasattr(self.__agreedToTerms, "as_dict") + else self.__agreedToTerms + ) + if self.__source is not None: + d["source"] = ( + self.__source.as_dict() + if hasattr(self.__source, "as_dict") + else self.__source + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__type[:20] + if isinstance(self.__type, bytes) + else self.__type + ), + limitedRepr( + self.__latestTerms[:20] + if isinstance(self.__latestTerms, bytes) + else self.__latestTerms + ), + limitedRepr( + self.__agreedToTerms[:20] + if isinstance(self.__agreedToTerms, bytes) + else self.__agreedToTerms + ), + limitedRepr( + self.__source[:20] + if isinstance(self.__source, bytes) + else self.__source + ), + ) + + class _account: + + _types_map = { + "isMinor": {"type": bool, "subtype": None}, + "suspectUnderage": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "isMinor": { + "required": True, + }, + "suspectUnderage": { + "required": True, + }, + } + + def __init__(self, isMinor: bool = None, suspectUnderage: bool = None): + pass + self.__isMinor = isMinor + self.__suspectUnderage = suspectUnderage + + def _get_isMinor(self): + return self.__isMinor + + def _set_isMinor(self, value): + if not isinstance(value, bool): + raise TypeError("isMinor must be bool") + + self.__isMinor = value + + isMinor = property(_get_isMinor, _set_isMinor) + + def _get_suspectUnderage(self): + return self.__suspectUnderage + + def _set_suspectUnderage(self, value): + if not isinstance(value, bool): + raise TypeError("suspectUnderage must be bool") + + self.__suspectUnderage = value + + suspectUnderage = property(_get_suspectUnderage, _set_suspectUnderage) + + @staticmethod + def from_dict(d): + v = {} + if "isMinor" in d: + v["isMinor"] = ( + bool.from_dict(d["isMinor"]) + if hasattr(bool, "from_dict") + else d["isMinor"] + ) + if "suspectUnderage" in d: + v["suspectUnderage"] = ( + bool.from_dict(d["suspectUnderage"]) + if hasattr(bool, "from_dict") + else d["suspectUnderage"] + ) + return StoreAuthenticateResp._subscriptionStatus._account(**v) + + def as_dict(self): + d = {} + if self.__isMinor is not None: + d["isMinor"] = ( + self.__isMinor.as_dict() + if hasattr(self.__isMinor, "as_dict") + else self.__isMinor + ) + if self.__suspectUnderage is not None: + d["suspectUnderage"] = ( + self.__suspectUnderage.as_dict() + if hasattr(self.__suspectUnderage, "as_dict") + else self.__suspectUnderage + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__isMinor[:20] + if isinstance(self.__isMinor, bytes) + else self.__isMinor + ), + limitedRepr( + self.__suspectUnderage[:20] + if isinstance(self.__suspectUnderage, bytes) + else self.__suspectUnderage + ), + ) + + class _family: + + _types_map = { + "hasFamily": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "hasFamily": { + "required": True, + }, + } + + def __init__(self, hasFamily: bool = None): + pass + self.__hasFamily = hasFamily + + def _get_hasFamily(self): + return self.__hasFamily + + def _set_hasFamily(self, value): + if not isinstance(value, bool): + raise TypeError("hasFamily must be bool") + + self.__hasFamily = value + + hasFamily = property(_get_hasFamily, _set_hasFamily) + + @staticmethod + def from_dict(d): + v = {} + if "hasFamily" in d: + v["hasFamily"] = ( + bool.from_dict(d["hasFamily"]) + if hasattr(bool, "from_dict") + else d["hasFamily"] + ) + return StoreAuthenticateResp._subscriptionStatus._family(**v) + + def as_dict(self): + d = {} + if self.__hasFamily is not None: + d["hasFamily"] = ( + self.__hasFamily.as_dict() + if hasattr(self.__hasFamily, "as_dict") + else self.__hasFamily + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__hasFamily[:20] + if isinstance(self.__hasFamily, bytes) + else self.__hasFamily + ) + ) + + _types_map = { + "terms": {"type": list, "subtype": _terms}, + "account": {"type": _account, "subtype": None}, + "family": {"type": _family, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "terms": { + "required": True, + }, + "account": { + "required": True, + }, + "family": { + "required": True, + }, + } + + def __init__( + self, + terms: List[_terms] = None, + account: _account = None, + family: _family = None, + ): + pass + self.__terms = terms + self.__account = account + self.__family = family + + def _get_terms(self): + return self.__terms + + def _set_terms(self, value): + if not isinstance(value, list): + raise TypeError("terms must be list") + if not all( + isinstance(i, StoreAuthenticateResp._subscriptionStatus._terms) + for i in value + ): + raise TypeError( + "terms list values must be StoreAuthenticateResp._subscriptionStatus._terms" + ) + + self.__terms = value + + terms = property(_get_terms, _set_terms) + + def _get_account(self): + return self.__account + + def _set_account(self, value): + if not isinstance( + value, StoreAuthenticateResp._subscriptionStatus._account + ): + raise TypeError( + "account must be StoreAuthenticateResp._subscriptionStatus._account" + ) + + self.__account = value + + account = property(_get_account, _set_account) + + def _get_family(self): + return self.__family + + def _set_family(self, value): + if not isinstance(value, StoreAuthenticateResp._subscriptionStatus._family): + raise TypeError( + "family must be StoreAuthenticateResp._subscriptionStatus._family" + ) + + self.__family = value + + family = property(_get_family, _set_family) + + @staticmethod + def from_dict(d): + v = {} + if "terms" in d: + v["terms"] = [ + StoreAuthenticateResp._subscriptionStatus._terms.from_dict(p) + if hasattr( + StoreAuthenticateResp._subscriptionStatus._terms, "from_dict" + ) + else p + for p in d["terms"] + ] + if "account" in d: + v["account"] = ( + StoreAuthenticateResp._subscriptionStatus._account.from_dict( + d["account"] + ) + if hasattr( + StoreAuthenticateResp._subscriptionStatus._account, "from_dict" + ) + else d["account"] + ) + if "family" in d: + v["family"] = ( + StoreAuthenticateResp._subscriptionStatus._family.from_dict( + d["family"] + ) + if hasattr( + StoreAuthenticateResp._subscriptionStatus._family, "from_dict" + ) + else d["family"] + ) + return StoreAuthenticateResp._subscriptionStatus(**v) + + def as_dict(self): + d = {} + if self.__terms is not None: + d["terms"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__terms + ] + if self.__account is not None: + d["account"] = ( + self.__account.as_dict() + if hasattr(self.__account, "as_dict") + else self.__account + ) + if self.__family is not None: + d["family"] = ( + self.__family.as_dict() + if hasattr(self.__family, "as_dict") + else self.__family + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__terms[:20] + if isinstance(self.__terms, bytes) + else self.__terms + ), + limitedRepr( + self.__account[:20] + if isinstance(self.__account, bytes) + else self.__account + ), + limitedRepr( + self.__family[:20] + if isinstance(self.__family, bytes) + else self.__family + ), + ) + + class _download_queue_info: + + _types_map = { + "download_queue_item_count": {"type": int, "subtype": None}, + "dsid": {"type": int, "subtype": None}, + "is_auto_download_machine": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "download_queue_item_count": { + "required": True, + }, + "dsid": { + "required": True, + }, + "is_auto_download_machine": { + "required": True, + }, + } + + def __init__( + self, + download_queue_item_count: int = None, + dsid: int = None, + is_auto_download_machine: bool = None, + ): + pass + self.__download_queue_item_count = download_queue_item_count + self.__dsid = dsid + self.__is_auto_download_machine = is_auto_download_machine + + def _get_download_queue_item_count(self): + return self.__download_queue_item_count + + def _set_download_queue_item_count(self, value): + if not isinstance(value, int): + raise TypeError("download_queue_item_count must be int") + + self.__download_queue_item_count = value + + download_queue_item_count = property( + _get_download_queue_item_count, _set_download_queue_item_count + ) + + def _get_dsid(self): + return self.__dsid + + def _set_dsid(self, value): + if not isinstance(value, int): + raise TypeError("dsid must be int") + + self.__dsid = value + + dsid = property(_get_dsid, _set_dsid) + + def _get_is_auto_download_machine(self): + return self.__is_auto_download_machine + + def _set_is_auto_download_machine(self, value): + if not isinstance(value, bool): + raise TypeError("is_auto_download_machine must be bool") + + self.__is_auto_download_machine = value + + is_auto_download_machine = property( + _get_is_auto_download_machine, _set_is_auto_download_machine + ) + + @staticmethod + def from_dict(d): + v = {} + if "download-queue-item-count" in d: + v["download_queue_item_count"] = ( + int.from_dict(d["download-queue-item-count"]) + if hasattr(int, "from_dict") + else d["download-queue-item-count"] + ) + if "dsid" in d: + v["dsid"] = ( + int.from_dict(d["dsid"]) if hasattr(int, "from_dict") else d["dsid"] + ) + if "is-auto-download-machine" in d: + v["is_auto_download_machine"] = ( + bool.from_dict(d["is-auto-download-machine"]) + if hasattr(bool, "from_dict") + else d["is-auto-download-machine"] + ) + return StoreAuthenticateResp._download_queue_info(**v) + + def as_dict(self): + d = {} + if self.__download_queue_item_count is not None: + d["download-queue-item-count"] = ( + self.__download_queue_item_count.as_dict() + if hasattr(self.__download_queue_item_count, "as_dict") + else self.__download_queue_item_count + ) + if self.__dsid is not None: + d["dsid"] = ( + self.__dsid.as_dict() + if hasattr(self.__dsid, "as_dict") + else self.__dsid + ) + if self.__is_auto_download_machine is not None: + d["is-auto-download-machine"] = ( + self.__is_auto_download_machine.as_dict() + if hasattr(self.__is_auto_download_machine, "as_dict") + else self.__is_auto_download_machine + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__download_queue_item_count[:20] + if isinstance(self.__download_queue_item_count, bytes) + else self.__download_queue_item_count + ), + limitedRepr( + self.__dsid[:20] if isinstance(self.__dsid, bytes) else self.__dsid + ), + limitedRepr( + self.__is_auto_download_machine[:20] + if isinstance(self.__is_auto_download_machine, bytes) + else self.__is_auto_download_machine + ), + ) + + class _dialog: + + _types_map = { + "m_allowed": {"type": bool, "subtype": None}, + "message": {"type": str, "subtype": None}, + "explanation": {"type": str, "subtype": None}, + "defaultButton": {"type": str, "subtype": None}, + "okButtonString": {"type": str, "subtype": None}, + "initialCheckboxValue": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "m_allowed": { + "required": True, + }, + "message": { + "required": True, + }, + "explanation": { + "required": True, + }, + "defaultButton": { + "required": True, + }, + "okButtonString": { + "required": True, + }, + "initialCheckboxValue": { + "required": True, + }, + } + + def __init__( + self, + m_allowed: bool = None, + message: str = None, + explanation: str = None, + defaultButton: str = None, + okButtonString: str = None, + initialCheckboxValue: bool = None, + ): + pass + self.__m_allowed = m_allowed + self.__message = message + self.__explanation = explanation + self.__defaultButton = defaultButton + self.__okButtonString = okButtonString + self.__initialCheckboxValue = initialCheckboxValue + + def _get_m_allowed(self): + return self.__m_allowed + + def _set_m_allowed(self, value): + if not isinstance(value, bool): + raise TypeError("m_allowed must be bool") + + self.__m_allowed = value + + m_allowed = property(_get_m_allowed, _set_m_allowed) + + def _get_message(self): + return self.__message + + def _set_message(self, value): + if not isinstance(value, str): + raise TypeError("message must be str") + + self.__message = value + + message = property(_get_message, _set_message) + + def _get_explanation(self): + return self.__explanation + + def _set_explanation(self, value): + if not isinstance(value, str): + raise TypeError("explanation must be str") + + self.__explanation = value + + explanation = property(_get_explanation, _set_explanation) + + def _get_defaultButton(self): + return self.__defaultButton + + def _set_defaultButton(self, value): + if not isinstance(value, str): + raise TypeError("defaultButton must be str") + + self.__defaultButton = value + + defaultButton = property(_get_defaultButton, _set_defaultButton) + + def _get_okButtonString(self): + return self.__okButtonString + + def _set_okButtonString(self, value): + if not isinstance(value, str): + raise TypeError("okButtonString must be str") + + self.__okButtonString = value + + okButtonString = property(_get_okButtonString, _set_okButtonString) + + def _get_initialCheckboxValue(self): + return self.__initialCheckboxValue + + def _set_initialCheckboxValue(self, value): + if not isinstance(value, bool): + raise TypeError("initialCheckboxValue must be bool") + + self.__initialCheckboxValue = value + + initialCheckboxValue = property( + _get_initialCheckboxValue, _set_initialCheckboxValue + ) + + @staticmethod + def from_dict(d): + v = {} + if "m-allowed" in d: + v["m_allowed"] = ( + bool.from_dict(d["m-allowed"]) + if hasattr(bool, "from_dict") + else d["m-allowed"] + ) + if "message" in d: + v["message"] = ( + str.from_dict(d["message"]) + if hasattr(str, "from_dict") + else d["message"] + ) + if "explanation" in d: + v["explanation"] = ( + str.from_dict(d["explanation"]) + if hasattr(str, "from_dict") + else d["explanation"] + ) + if "defaultButton" in d: + v["defaultButton"] = ( + str.from_dict(d["defaultButton"]) + if hasattr(str, "from_dict") + else d["defaultButton"] + ) + if "okButtonString" in d: + v["okButtonString"] = ( + str.from_dict(d["okButtonString"]) + if hasattr(str, "from_dict") + else d["okButtonString"] + ) + if "initialCheckboxValue" in d: + v["initialCheckboxValue"] = ( + bool.from_dict(d["initialCheckboxValue"]) + if hasattr(bool, "from_dict") + else d["initialCheckboxValue"] + ) + return StoreAuthenticateResp._dialog(**v) + + def as_dict(self): + d = {} + if self.__m_allowed is not None: + d["m-allowed"] = ( + self.__m_allowed.as_dict() + if hasattr(self.__m_allowed, "as_dict") + else self.__m_allowed + ) + if self.__message is not None: + d["message"] = ( + self.__message.as_dict() + if hasattr(self.__message, "as_dict") + else self.__message + ) + if self.__explanation is not None: + d["explanation"] = ( + self.__explanation.as_dict() + if hasattr(self.__explanation, "as_dict") + else self.__explanation + ) + if self.__defaultButton is not None: + d["defaultButton"] = ( + self.__defaultButton.as_dict() + if hasattr(self.__defaultButton, "as_dict") + else self.__defaultButton + ) + if self.__okButtonString is not None: + d["okButtonString"] = ( + self.__okButtonString.as_dict() + if hasattr(self.__okButtonString, "as_dict") + else self.__okButtonString + ) + if self.__initialCheckboxValue is not None: + d["initialCheckboxValue"] = ( + self.__initialCheckboxValue.as_dict() + if hasattr(self.__initialCheckboxValue, "as_dict") + else self.__initialCheckboxValue + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__m_allowed[:20] + if isinstance(self.__m_allowed, bytes) + else self.__m_allowed + ), + limitedRepr( + self.__message[:20] + if isinstance(self.__message, bytes) + else self.__message + ), + limitedRepr( + self.__explanation[:20] + if isinstance(self.__explanation, bytes) + else self.__explanation + ), + limitedRepr( + self.__defaultButton[:20] + if isinstance(self.__defaultButton, bytes) + else self.__defaultButton + ), + limitedRepr( + self.__okButtonString[:20] + if isinstance(self.__okButtonString, bytes) + else self.__okButtonString + ), + limitedRepr( + self.__initialCheckboxValue[:20] + if isinstance(self.__initialCheckboxValue, bytes) + else self.__initialCheckboxValue + ), + ) + + class _privacyAcknowledgement: + + _types_map = { + "com_apple_onboarding_appstore": {"type": int, "subtype": None}, + "com_apple_onboarding_applemusic": {"type": int, "subtype": None}, + "com_apple_onboarding_videos": {"type": int, "subtype": None}, + "com_apple_onboarding_itunesstore": {"type": int, "subtype": None}, + "com_apple_onboarding_itunesu": {"type": int, "subtype": None}, + "com_apple_onboarding_applearcade": {"type": int, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "com_apple_onboarding_appstore": { + "required": True, + }, + "com_apple_onboarding_applemusic": { + "required": True, + }, + "com_apple_onboarding_videos": { + "required": True, + }, + "com_apple_onboarding_itunesstore": { + "required": True, + }, + "com_apple_onboarding_itunesu": { + "required": True, + }, + "com_apple_onboarding_applearcade": { + "required": True, + }, + } + + def __init__( + self, + com_apple_onboarding_appstore: int = None, + com_apple_onboarding_applemusic: int = None, + com_apple_onboarding_videos: int = None, + com_apple_onboarding_itunesstore: int = None, + com_apple_onboarding_itunesu: int = None, + com_apple_onboarding_applearcade: int = None, + ): + pass + self.__com_apple_onboarding_appstore = com_apple_onboarding_appstore + self.__com_apple_onboarding_applemusic = com_apple_onboarding_applemusic + self.__com_apple_onboarding_videos = com_apple_onboarding_videos + self.__com_apple_onboarding_itunesstore = com_apple_onboarding_itunesstore + self.__com_apple_onboarding_itunesu = com_apple_onboarding_itunesu + self.__com_apple_onboarding_applearcade = com_apple_onboarding_applearcade + + def _get_com_apple_onboarding_appstore(self): + return self.__com_apple_onboarding_appstore + + def _set_com_apple_onboarding_appstore(self, value): + if not isinstance(value, int): + raise TypeError("com_apple_onboarding_appstore must be int") + + self.__com_apple_onboarding_appstore = value + + com_apple_onboarding_appstore = property( + _get_com_apple_onboarding_appstore, _set_com_apple_onboarding_appstore + ) + + def _get_com_apple_onboarding_applemusic(self): + return self.__com_apple_onboarding_applemusic + + def _set_com_apple_onboarding_applemusic(self, value): + if not isinstance(value, int): + raise TypeError("com_apple_onboarding_applemusic must be int") + + self.__com_apple_onboarding_applemusic = value + + com_apple_onboarding_applemusic = property( + _get_com_apple_onboarding_applemusic, _set_com_apple_onboarding_applemusic + ) + + def _get_com_apple_onboarding_videos(self): + return self.__com_apple_onboarding_videos + + def _set_com_apple_onboarding_videos(self, value): + if not isinstance(value, int): + raise TypeError("com_apple_onboarding_videos must be int") + + self.__com_apple_onboarding_videos = value + + com_apple_onboarding_videos = property( + _get_com_apple_onboarding_videos, _set_com_apple_onboarding_videos + ) + + def _get_com_apple_onboarding_itunesstore(self): + return self.__com_apple_onboarding_itunesstore + + def _set_com_apple_onboarding_itunesstore(self, value): + if not isinstance(value, int): + raise TypeError("com_apple_onboarding_itunesstore must be int") + + self.__com_apple_onboarding_itunesstore = value + + com_apple_onboarding_itunesstore = property( + _get_com_apple_onboarding_itunesstore, _set_com_apple_onboarding_itunesstore + ) + + def _get_com_apple_onboarding_itunesu(self): + return self.__com_apple_onboarding_itunesu + + def _set_com_apple_onboarding_itunesu(self, value): + if not isinstance(value, int): + raise TypeError("com_apple_onboarding_itunesu must be int") + + self.__com_apple_onboarding_itunesu = value + + com_apple_onboarding_itunesu = property( + _get_com_apple_onboarding_itunesu, _set_com_apple_onboarding_itunesu + ) + + def _get_com_apple_onboarding_applearcade(self): + return self.__com_apple_onboarding_applearcade + + def _set_com_apple_onboarding_applearcade(self, value): + if not isinstance(value, int): + raise TypeError("com_apple_onboarding_applearcade must be int") + + self.__com_apple_onboarding_applearcade = value + + com_apple_onboarding_applearcade = property( + _get_com_apple_onboarding_applearcade, _set_com_apple_onboarding_applearcade + ) + + @staticmethod + def from_dict(d): + v = {} + if "com.apple.onboarding.appstore" in d: + v["com_apple_onboarding_appstore"] = ( + int.from_dict(d["com.apple.onboarding.appstore"]) + if hasattr(int, "from_dict") + else d["com.apple.onboarding.appstore"] + ) + if "com.apple.onboarding.applemusic" in d: + v["com_apple_onboarding_applemusic"] = ( + int.from_dict(d["com.apple.onboarding.applemusic"]) + if hasattr(int, "from_dict") + else d["com.apple.onboarding.applemusic"] + ) + if "com.apple.onboarding.videos" in d: + v["com_apple_onboarding_videos"] = ( + int.from_dict(d["com.apple.onboarding.videos"]) + if hasattr(int, "from_dict") + else d["com.apple.onboarding.videos"] + ) + if "com.apple.onboarding.itunesstore" in d: + v["com_apple_onboarding_itunesstore"] = ( + int.from_dict(d["com.apple.onboarding.itunesstore"]) + if hasattr(int, "from_dict") + else d["com.apple.onboarding.itunesstore"] + ) + if "com.apple.onboarding.itunesu" in d: + v["com_apple_onboarding_itunesu"] = ( + int.from_dict(d["com.apple.onboarding.itunesu"]) + if hasattr(int, "from_dict") + else d["com.apple.onboarding.itunesu"] + ) + if "com.apple.onboarding.applearcade" in d: + v["com_apple_onboarding_applearcade"] = ( + int.from_dict(d["com.apple.onboarding.applearcade"]) + if hasattr(int, "from_dict") + else d["com.apple.onboarding.applearcade"] + ) + return StoreAuthenticateResp._privacyAcknowledgement(**v) + + def as_dict(self): + d = {} + if self.__com_apple_onboarding_appstore is not None: + d["com.apple.onboarding.appstore"] = ( + self.__com_apple_onboarding_appstore.as_dict() + if hasattr(self.__com_apple_onboarding_appstore, "as_dict") + else self.__com_apple_onboarding_appstore + ) + if self.__com_apple_onboarding_applemusic is not None: + d["com.apple.onboarding.applemusic"] = ( + self.__com_apple_onboarding_applemusic.as_dict() + if hasattr(self.__com_apple_onboarding_applemusic, "as_dict") + else self.__com_apple_onboarding_applemusic + ) + if self.__com_apple_onboarding_videos is not None: + d["com.apple.onboarding.videos"] = ( + self.__com_apple_onboarding_videos.as_dict() + if hasattr(self.__com_apple_onboarding_videos, "as_dict") + else self.__com_apple_onboarding_videos + ) + if self.__com_apple_onboarding_itunesstore is not None: + d["com.apple.onboarding.itunesstore"] = ( + self.__com_apple_onboarding_itunesstore.as_dict() + if hasattr(self.__com_apple_onboarding_itunesstore, "as_dict") + else self.__com_apple_onboarding_itunesstore + ) + if self.__com_apple_onboarding_itunesu is not None: + d["com.apple.onboarding.itunesu"] = ( + self.__com_apple_onboarding_itunesu.as_dict() + if hasattr(self.__com_apple_onboarding_itunesu, "as_dict") + else self.__com_apple_onboarding_itunesu + ) + if self.__com_apple_onboarding_applearcade is not None: + d["com.apple.onboarding.applearcade"] = ( + self.__com_apple_onboarding_applearcade.as_dict() + if hasattr(self.__com_apple_onboarding_applearcade, "as_dict") + else self.__com_apple_onboarding_applearcade + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__com_apple_onboarding_appstore[:20] + if isinstance(self.__com_apple_onboarding_appstore, bytes) + else self.__com_apple_onboarding_appstore + ), + limitedRepr( + self.__com_apple_onboarding_applemusic[:20] + if isinstance(self.__com_apple_onboarding_applemusic, bytes) + else self.__com_apple_onboarding_applemusic + ), + limitedRepr( + self.__com_apple_onboarding_videos[:20] + if isinstance(self.__com_apple_onboarding_videos, bytes) + else self.__com_apple_onboarding_videos + ), + limitedRepr( + self.__com_apple_onboarding_itunesstore[:20] + if isinstance(self.__com_apple_onboarding_itunesstore, bytes) + else self.__com_apple_onboarding_itunesstore + ), + limitedRepr( + self.__com_apple_onboarding_itunesu[:20] + if isinstance(self.__com_apple_onboarding_itunesu, bytes) + else self.__com_apple_onboarding_itunesu + ), + limitedRepr( + self.__com_apple_onboarding_applearcade[:20] + if isinstance(self.__com_apple_onboarding_applearcade, bytes) + else self.__com_apple_onboarding_applearcade + ), + ) + + class _action: + + _types_map = { + "kind": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "kind": { + "required": True, + }, + } + + def __init__(self, kind: str = None): + pass + self.__kind = kind + + def _get_kind(self): + return self.__kind + + def _set_kind(self, value): + if not isinstance(value, str): + raise TypeError("kind must be str") + + self.__kind = value + + kind = property(_get_kind, _set_kind) + + @staticmethod + def from_dict(d): + v = {} + if "kind" in d: + v["kind"] = ( + str.from_dict(d["kind"]) if hasattr(str, "from_dict") else d["kind"] + ) + return StoreAuthenticateResp._action(**v) + + def as_dict(self): + d = {} + if self.__kind is not None: + d["kind"] = ( + self.__kind.as_dict() + if hasattr(self.__kind, "as_dict") + else self.__kind + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__kind[:20] if isinstance(self.__kind, bytes) else self.__kind + ) + ) + + class _accountInfo: + class _address: + + _types_map = { + "firstName": {"type": str, "subtype": None}, + "lastName": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "firstName": { + "required": True, + }, + "lastName": { + "required": True, + }, + } + + def __init__(self, firstName: str = None, lastName: str = None): + pass + self.__firstName = firstName + self.__lastName = lastName + + def _get_firstName(self): + return self.__firstName + + def _set_firstName(self, value): + if not isinstance(value, str): + raise TypeError("firstName must be str") + + self.__firstName = value + + firstName = property(_get_firstName, _set_firstName) + + def _get_lastName(self): + return self.__lastName + + def _set_lastName(self, value): + if not isinstance(value, str): + raise TypeError("lastName must be str") + + self.__lastName = value + + lastName = property(_get_lastName, _set_lastName) + + @staticmethod + def from_dict(d): + v = {} + if "firstName" in d: + v["firstName"] = ( + str.from_dict(d["firstName"]) + if hasattr(str, "from_dict") + else d["firstName"] + ) + if "lastName" in d: + v["lastName"] = ( + str.from_dict(d["lastName"]) + if hasattr(str, "from_dict") + else d["lastName"] + ) + return StoreAuthenticateResp._accountInfo._address(**v) + + def as_dict(self): + d = {} + if self.__firstName is not None: + d["firstName"] = ( + self.__firstName.as_dict() + if hasattr(self.__firstName, "as_dict") + else self.__firstName + ) + if self.__lastName is not None: + d["lastName"] = ( + self.__lastName.as_dict() + if hasattr(self.__lastName, "as_dict") + else self.__lastName + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__firstName[:20] + if isinstance(self.__firstName, bytes) + else self.__firstName + ), + limitedRepr( + self.__lastName[:20] + if isinstance(self.__lastName, bytes) + else self.__lastName + ), + ) + + _types_map = { + "appleId": {"type": str, "subtype": None}, + "address": {"type": _address, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "appleId": { + "required": True, + }, + "address": { + "required": True, + }, + } + + def __init__(self, appleId: str = None, address: _address = None): + pass + self.__appleId = appleId + self.__address = address + + def _get_appleId(self): + return self.__appleId + + def _set_appleId(self, value): + if not isinstance(value, str): + raise TypeError("appleId must be str") + + self.__appleId = value + + appleId = property(_get_appleId, _set_appleId) + + def _get_address(self): + return self.__address + + def _set_address(self, value): + if not isinstance(value, StoreAuthenticateResp._accountInfo._address): + raise TypeError( + "address must be StoreAuthenticateResp._accountInfo._address" + ) + + self.__address = value + + address = property(_get_address, _set_address) + + @staticmethod + def from_dict(d): + v = {} + if "appleId" in d: + v["appleId"] = ( + str.from_dict(d["appleId"]) + if hasattr(str, "from_dict") + else d["appleId"] + ) + if "address" in d: + v["address"] = ( + StoreAuthenticateResp._accountInfo._address.from_dict(d["address"]) + if hasattr(StoreAuthenticateResp._accountInfo._address, "from_dict") + else d["address"] + ) + return StoreAuthenticateResp._accountInfo(**v) + + def as_dict(self): + d = {} + if self.__appleId is not None: + d["appleId"] = ( + self.__appleId.as_dict() + if hasattr(self.__appleId, "as_dict") + else self.__appleId + ) + if self.__address is not None: + d["address"] = ( + self.__address.as_dict() + if hasattr(self.__address, "as_dict") + else self.__address + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__appleId[:20] + if isinstance(self.__appleId, bytes) + else self.__appleId + ), + limitedRepr( + self.__address[:20] + if isinstance(self.__address, bytes) + else self.__address + ), + ) + + class _accountFlags: + + _types_map = { + "personalization": {"type": bool, "subtype": None}, + "underThirteen": {"type": bool, "subtype": None}, + "identityLastVerified": {"type": int, "subtype": None}, + "verifiedExpirationDate": {"type": int, "subtype": None}, + "retailDemo": {"type": bool, "subtype": None}, + "autoPlay": {"type": bool, "subtype": None}, + "isDisabledAccount": {"type": bool, "subtype": None}, + "isRestrictedAccount": {"type": bool, "subtype": None}, + "isManagedAccount": {"type": bool, "subtype": None}, + "isInRestrictedRegion": {"type": bool, "subtype": None}, + "accountFlagsVersion": {"type": int, "subtype": None}, + "hasAgreedToTerms": {"type": bool, "subtype": None}, + "hasAgreedToAppClipTerms": {"type": bool, "subtype": None}, + "hasWatchHardwareOffer": {"type": bool, "subtype": None}, + "isInFamily": {"type": bool, "subtype": None}, + "hasSubscriptionFamilySharingEnabled": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "personalization": { + "required": True, + }, + "underThirteen": { + "required": True, + }, + "identityLastVerified": { + "required": True, + }, + "verifiedExpirationDate": { + "required": True, + }, + "retailDemo": { + "required": True, + }, + "autoPlay": { + "required": True, + }, + "isDisabledAccount": { + "required": True, + }, + "isRestrictedAccount": { + "required": True, + }, + "isManagedAccount": { + "required": True, + }, + "isInRestrictedRegion": { + "required": True, + }, + "accountFlagsVersion": { + "required": True, + }, + "hasAgreedToTerms": { + "required": True, + }, + "hasAgreedToAppClipTerms": { + "required": True, + }, + "hasWatchHardwareOffer": { + "required": True, + }, + "isInFamily": { + "required": True, + }, + "hasSubscriptionFamilySharingEnabled": { + "required": True, + }, + } + + def __init__( + self, + personalization: bool = None, + underThirteen: bool = None, + identityLastVerified: int = None, + verifiedExpirationDate: int = None, + retailDemo: bool = None, + autoPlay: bool = None, + isDisabledAccount: bool = None, + isRestrictedAccount: bool = None, + isManagedAccount: bool = None, + isInRestrictedRegion: bool = None, + accountFlagsVersion: int = None, + hasAgreedToTerms: bool = None, + hasAgreedToAppClipTerms: bool = None, + hasWatchHardwareOffer: bool = None, + isInFamily: bool = None, + hasSubscriptionFamilySharingEnabled: bool = None, + ): + pass + self.__personalization = personalization + self.__underThirteen = underThirteen + self.__identityLastVerified = identityLastVerified + self.__verifiedExpirationDate = verifiedExpirationDate + self.__retailDemo = retailDemo + self.__autoPlay = autoPlay + self.__isDisabledAccount = isDisabledAccount + self.__isRestrictedAccount = isRestrictedAccount + self.__isManagedAccount = isManagedAccount + self.__isInRestrictedRegion = isInRestrictedRegion + self.__accountFlagsVersion = accountFlagsVersion + self.__hasAgreedToTerms = hasAgreedToTerms + self.__hasAgreedToAppClipTerms = hasAgreedToAppClipTerms + self.__hasWatchHardwareOffer = hasWatchHardwareOffer + self.__isInFamily = isInFamily + self.__hasSubscriptionFamilySharingEnabled = ( + hasSubscriptionFamilySharingEnabled + ) + + def _get_personalization(self): + return self.__personalization + + def _set_personalization(self, value): + if not isinstance(value, bool): + raise TypeError("personalization must be bool") + + self.__personalization = value + + personalization = property(_get_personalization, _set_personalization) + + def _get_underThirteen(self): + return self.__underThirteen + + def _set_underThirteen(self, value): + if not isinstance(value, bool): + raise TypeError("underThirteen must be bool") + + self.__underThirteen = value + + underThirteen = property(_get_underThirteen, _set_underThirteen) + + def _get_identityLastVerified(self): + return self.__identityLastVerified + + def _set_identityLastVerified(self, value): + if not isinstance(value, int): + raise TypeError("identityLastVerified must be int") + + self.__identityLastVerified = value + + identityLastVerified = property( + _get_identityLastVerified, _set_identityLastVerified + ) + + def _get_verifiedExpirationDate(self): + return self.__verifiedExpirationDate + + def _set_verifiedExpirationDate(self, value): + if not isinstance(value, int): + raise TypeError("verifiedExpirationDate must be int") + + self.__verifiedExpirationDate = value + + verifiedExpirationDate = property( + _get_verifiedExpirationDate, _set_verifiedExpirationDate + ) + + def _get_retailDemo(self): + return self.__retailDemo + + def _set_retailDemo(self, value): + if not isinstance(value, bool): + raise TypeError("retailDemo must be bool") + + self.__retailDemo = value + + retailDemo = property(_get_retailDemo, _set_retailDemo) + + def _get_autoPlay(self): + return self.__autoPlay + + def _set_autoPlay(self, value): + if not isinstance(value, bool): + raise TypeError("autoPlay must be bool") + + self.__autoPlay = value + + autoPlay = property(_get_autoPlay, _set_autoPlay) + + def _get_isDisabledAccount(self): + return self.__isDisabledAccount + + def _set_isDisabledAccount(self, value): + if not isinstance(value, bool): + raise TypeError("isDisabledAccount must be bool") + + self.__isDisabledAccount = value + + isDisabledAccount = property(_get_isDisabledAccount, _set_isDisabledAccount) + + def _get_isRestrictedAccount(self): + return self.__isRestrictedAccount + + def _set_isRestrictedAccount(self, value): + if not isinstance(value, bool): + raise TypeError("isRestrictedAccount must be bool") + + self.__isRestrictedAccount = value + + isRestrictedAccount = property( + _get_isRestrictedAccount, _set_isRestrictedAccount + ) + + def _get_isManagedAccount(self): + return self.__isManagedAccount + + def _set_isManagedAccount(self, value): + if not isinstance(value, bool): + raise TypeError("isManagedAccount must be bool") + + self.__isManagedAccount = value + + isManagedAccount = property(_get_isManagedAccount, _set_isManagedAccount) + + def _get_isInRestrictedRegion(self): + return self.__isInRestrictedRegion + + def _set_isInRestrictedRegion(self, value): + if not isinstance(value, bool): + raise TypeError("isInRestrictedRegion must be bool") + + self.__isInRestrictedRegion = value + + isInRestrictedRegion = property( + _get_isInRestrictedRegion, _set_isInRestrictedRegion + ) + + def _get_accountFlagsVersion(self): + return self.__accountFlagsVersion + + def _set_accountFlagsVersion(self, value): + if not isinstance(value, int): + raise TypeError("accountFlagsVersion must be int") + + self.__accountFlagsVersion = value + + accountFlagsVersion = property( + _get_accountFlagsVersion, _set_accountFlagsVersion + ) + + def _get_hasAgreedToTerms(self): + return self.__hasAgreedToTerms + + def _set_hasAgreedToTerms(self, value): + if not isinstance(value, bool): + raise TypeError("hasAgreedToTerms must be bool") + + self.__hasAgreedToTerms = value + + hasAgreedToTerms = property(_get_hasAgreedToTerms, _set_hasAgreedToTerms) + + def _get_hasAgreedToAppClipTerms(self): + return self.__hasAgreedToAppClipTerms + + def _set_hasAgreedToAppClipTerms(self, value): + if not isinstance(value, bool): + raise TypeError("hasAgreedToAppClipTerms must be bool") + + self.__hasAgreedToAppClipTerms = value + + hasAgreedToAppClipTerms = property( + _get_hasAgreedToAppClipTerms, _set_hasAgreedToAppClipTerms + ) + + def _get_hasWatchHardwareOffer(self): + return self.__hasWatchHardwareOffer + + def _set_hasWatchHardwareOffer(self, value): + if not isinstance(value, bool): + raise TypeError("hasWatchHardwareOffer must be bool") + + self.__hasWatchHardwareOffer = value + + hasWatchHardwareOffer = property( + _get_hasWatchHardwareOffer, _set_hasWatchHardwareOffer + ) + + def _get_isInFamily(self): + return self.__isInFamily + + def _set_isInFamily(self, value): + if not isinstance(value, bool): + raise TypeError("isInFamily must be bool") + + self.__isInFamily = value + + isInFamily = property(_get_isInFamily, _set_isInFamily) + + def _get_hasSubscriptionFamilySharingEnabled(self): + return self.__hasSubscriptionFamilySharingEnabled + + def _set_hasSubscriptionFamilySharingEnabled(self, value): + if not isinstance(value, bool): + raise TypeError("hasSubscriptionFamilySharingEnabled must be bool") + + self.__hasSubscriptionFamilySharingEnabled = value + + hasSubscriptionFamilySharingEnabled = property( + _get_hasSubscriptionFamilySharingEnabled, + _set_hasSubscriptionFamilySharingEnabled, + ) + + @staticmethod + def from_dict(d): + v = {} + if "personalization" in d: + v["personalization"] = ( + bool.from_dict(d["personalization"]) + if hasattr(bool, "from_dict") + else d["personalization"] + ) + if "underThirteen" in d: + v["underThirteen"] = ( + bool.from_dict(d["underThirteen"]) + if hasattr(bool, "from_dict") + else d["underThirteen"] + ) + if "identityLastVerified" in d: + v["identityLastVerified"] = ( + int.from_dict(d["identityLastVerified"]) + if hasattr(int, "from_dict") + else d["identityLastVerified"] + ) + if "verifiedExpirationDate" in d: + v["verifiedExpirationDate"] = ( + int.from_dict(d["verifiedExpirationDate"]) + if hasattr(int, "from_dict") + else d["verifiedExpirationDate"] + ) + if "retailDemo" in d: + v["retailDemo"] = ( + bool.from_dict(d["retailDemo"]) + if hasattr(bool, "from_dict") + else d["retailDemo"] + ) + if "autoPlay" in d: + v["autoPlay"] = ( + bool.from_dict(d["autoPlay"]) + if hasattr(bool, "from_dict") + else d["autoPlay"] + ) + if "isDisabledAccount" in d: + v["isDisabledAccount"] = ( + bool.from_dict(d["isDisabledAccount"]) + if hasattr(bool, "from_dict") + else d["isDisabledAccount"] + ) + if "isRestrictedAccount" in d: + v["isRestrictedAccount"] = ( + bool.from_dict(d["isRestrictedAccount"]) + if hasattr(bool, "from_dict") + else d["isRestrictedAccount"] + ) + if "isManagedAccount" in d: + v["isManagedAccount"] = ( + bool.from_dict(d["isManagedAccount"]) + if hasattr(bool, "from_dict") + else d["isManagedAccount"] + ) + if "isInRestrictedRegion" in d: + v["isInRestrictedRegion"] = ( + bool.from_dict(d["isInRestrictedRegion"]) + if hasattr(bool, "from_dict") + else d["isInRestrictedRegion"] + ) + if "accountFlagsVersion" in d: + v["accountFlagsVersion"] = ( + int.from_dict(d["accountFlagsVersion"]) + if hasattr(int, "from_dict") + else d["accountFlagsVersion"] + ) + if "hasAgreedToTerms" in d: + v["hasAgreedToTerms"] = ( + bool.from_dict(d["hasAgreedToTerms"]) + if hasattr(bool, "from_dict") + else d["hasAgreedToTerms"] + ) + if "hasAgreedToAppClipTerms" in d: + v["hasAgreedToAppClipTerms"] = ( + bool.from_dict(d["hasAgreedToAppClipTerms"]) + if hasattr(bool, "from_dict") + else d["hasAgreedToAppClipTerms"] + ) + if "hasWatchHardwareOffer" in d: + v["hasWatchHardwareOffer"] = ( + bool.from_dict(d["hasWatchHardwareOffer"]) + if hasattr(bool, "from_dict") + else d["hasWatchHardwareOffer"] + ) + if "isInFamily" in d: + v["isInFamily"] = ( + bool.from_dict(d["isInFamily"]) + if hasattr(bool, "from_dict") + else d["isInFamily"] + ) + if "hasSubscriptionFamilySharingEnabled" in d: + v["hasSubscriptionFamilySharingEnabled"] = ( + bool.from_dict(d["hasSubscriptionFamilySharingEnabled"]) + if hasattr(bool, "from_dict") + else d["hasSubscriptionFamilySharingEnabled"] + ) + return StoreAuthenticateResp._accountFlags(**v) + + def as_dict(self): + d = {} + if self.__personalization is not None: + d["personalization"] = ( + self.__personalization.as_dict() + if hasattr(self.__personalization, "as_dict") + else self.__personalization + ) + if self.__underThirteen is not None: + d["underThirteen"] = ( + self.__underThirteen.as_dict() + if hasattr(self.__underThirteen, "as_dict") + else self.__underThirteen + ) + if self.__identityLastVerified is not None: + d["identityLastVerified"] = ( + self.__identityLastVerified.as_dict() + if hasattr(self.__identityLastVerified, "as_dict") + else self.__identityLastVerified + ) + if self.__verifiedExpirationDate is not None: + d["verifiedExpirationDate"] = ( + self.__verifiedExpirationDate.as_dict() + if hasattr(self.__verifiedExpirationDate, "as_dict") + else self.__verifiedExpirationDate + ) + if self.__retailDemo is not None: + d["retailDemo"] = ( + self.__retailDemo.as_dict() + if hasattr(self.__retailDemo, "as_dict") + else self.__retailDemo + ) + if self.__autoPlay is not None: + d["autoPlay"] = ( + self.__autoPlay.as_dict() + if hasattr(self.__autoPlay, "as_dict") + else self.__autoPlay + ) + if self.__isDisabledAccount is not None: + d["isDisabledAccount"] = ( + self.__isDisabledAccount.as_dict() + if hasattr(self.__isDisabledAccount, "as_dict") + else self.__isDisabledAccount + ) + if self.__isRestrictedAccount is not None: + d["isRestrictedAccount"] = ( + self.__isRestrictedAccount.as_dict() + if hasattr(self.__isRestrictedAccount, "as_dict") + else self.__isRestrictedAccount + ) + if self.__isManagedAccount is not None: + d["isManagedAccount"] = ( + self.__isManagedAccount.as_dict() + if hasattr(self.__isManagedAccount, "as_dict") + else self.__isManagedAccount + ) + if self.__isInRestrictedRegion is not None: + d["isInRestrictedRegion"] = ( + self.__isInRestrictedRegion.as_dict() + if hasattr(self.__isInRestrictedRegion, "as_dict") + else self.__isInRestrictedRegion + ) + if self.__accountFlagsVersion is not None: + d["accountFlagsVersion"] = ( + self.__accountFlagsVersion.as_dict() + if hasattr(self.__accountFlagsVersion, "as_dict") + else self.__accountFlagsVersion + ) + if self.__hasAgreedToTerms is not None: + d["hasAgreedToTerms"] = ( + self.__hasAgreedToTerms.as_dict() + if hasattr(self.__hasAgreedToTerms, "as_dict") + else self.__hasAgreedToTerms + ) + if self.__hasAgreedToAppClipTerms is not None: + d["hasAgreedToAppClipTerms"] = ( + self.__hasAgreedToAppClipTerms.as_dict() + if hasattr(self.__hasAgreedToAppClipTerms, "as_dict") + else self.__hasAgreedToAppClipTerms + ) + if self.__hasWatchHardwareOffer is not None: + d["hasWatchHardwareOffer"] = ( + self.__hasWatchHardwareOffer.as_dict() + if hasattr(self.__hasWatchHardwareOffer, "as_dict") + else self.__hasWatchHardwareOffer + ) + if self.__isInFamily is not None: + d["isInFamily"] = ( + self.__isInFamily.as_dict() + if hasattr(self.__isInFamily, "as_dict") + else self.__isInFamily + ) + if self.__hasSubscriptionFamilySharingEnabled is not None: + d["hasSubscriptionFamilySharingEnabled"] = ( + self.__hasSubscriptionFamilySharingEnabled.as_dict() + if hasattr(self.__hasSubscriptionFamilySharingEnabled, "as_dict") + else self.__hasSubscriptionFamilySharingEnabled + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__personalization[:20] + if isinstance(self.__personalization, bytes) + else self.__personalization + ), + limitedRepr( + self.__underThirteen[:20] + if isinstance(self.__underThirteen, bytes) + else self.__underThirteen + ), + limitedRepr( + self.__identityLastVerified[:20] + if isinstance(self.__identityLastVerified, bytes) + else self.__identityLastVerified + ), + limitedRepr( + self.__verifiedExpirationDate[:20] + if isinstance(self.__verifiedExpirationDate, bytes) + else self.__verifiedExpirationDate + ), + limitedRepr( + self.__retailDemo[:20] + if isinstance(self.__retailDemo, bytes) + else self.__retailDemo + ), + limitedRepr( + self.__autoPlay[:20] + if isinstance(self.__autoPlay, bytes) + else self.__autoPlay + ), + limitedRepr( + self.__isDisabledAccount[:20] + if isinstance(self.__isDisabledAccount, bytes) + else self.__isDisabledAccount + ), + limitedRepr( + self.__isRestrictedAccount[:20] + if isinstance(self.__isRestrictedAccount, bytes) + else self.__isRestrictedAccount + ), + limitedRepr( + self.__isManagedAccount[:20] + if isinstance(self.__isManagedAccount, bytes) + else self.__isManagedAccount + ), + limitedRepr( + self.__isInRestrictedRegion[:20] + if isinstance(self.__isInRestrictedRegion, bytes) + else self.__isInRestrictedRegion + ), + limitedRepr( + self.__accountFlagsVersion[:20] + if isinstance(self.__accountFlagsVersion, bytes) + else self.__accountFlagsVersion + ), + limitedRepr( + self.__hasAgreedToTerms[:20] + if isinstance(self.__hasAgreedToTerms, bytes) + else self.__hasAgreedToTerms + ), + limitedRepr( + self.__hasAgreedToAppClipTerms[:20] + if isinstance(self.__hasAgreedToAppClipTerms, bytes) + else self.__hasAgreedToAppClipTerms + ), + limitedRepr( + self.__hasWatchHardwareOffer[:20] + if isinstance(self.__hasWatchHardwareOffer, bytes) + else self.__hasWatchHardwareOffer + ), + limitedRepr( + self.__isInFamily[:20] + if isinstance(self.__isInFamily, bytes) + else self.__isInFamily + ), + limitedRepr( + self.__hasSubscriptionFamilySharingEnabled[:20] + if isinstance(self.__hasSubscriptionFamilySharingEnabled, bytes) + else self.__hasSubscriptionFamilySharingEnabled + ), + ) + + _types_map = { + "pings": {"type": list, "subtype": float}, + "cancel_purchase_batch": {"type": bool, "subtype": None}, + "customerMessage": {"type": str, "subtype": None}, + "failureType": {"type": str, "subtype": None}, + "accountInfo": {"type": _accountInfo, "subtype": None}, + "passwordToken": {"type": str, "subtype": None}, + "clearToken": {"type": str, "subtype": None}, + "m_allowed": {"type": bool, "subtype": None}, + "is_cloud_enabled": {"type": str, "subtype": None}, + "dsPersonId": {"type": str, "subtype": None}, + "creditDisplay": {"type": str, "subtype": None}, + "creditBalance": {"type": str, "subtype": None}, + "freeSongBalance": {"type": str, "subtype": None}, + "isManagedStudent": {"type": bool, "subtype": None}, + "action": {"type": _action, "subtype": None}, + "subscriptionStatus": {"type": _subscriptionStatus, "subtype": None}, + "accountFlags": {"type": _accountFlags, "subtype": None}, + "status": {"type": int, "subtype": None}, + "download_queue_info": {"type": _download_queue_info, "subtype": None}, + "privacyAcknowledgement": {"type": _privacyAcknowledgement, "subtype": None}, + "dialog": {"type": _dialog, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "pings": { + "required": True, + }, + "cancel_purchase_batch": { + "required": False, + }, + "customerMessage": { + "required": False, + }, + "failureType": { + "required": False, + }, + "accountInfo": { + "required": True, + }, + "passwordToken": { + "required": True, + }, + "clearToken": { + "required": True, + }, + "m_allowed": { + "required": True, + }, + "is_cloud_enabled": { + "required": True, + }, + "dsPersonId": { + "required": True, + }, + "creditDisplay": { + "required": True, + }, + "creditBalance": { + "required": True, + }, + "freeSongBalance": { + "required": True, + }, + "isManagedStudent": { + "required": True, + }, + "action": { + "required": True, + }, + "subscriptionStatus": { + "required": True, + }, + "accountFlags": { + "required": True, + }, + "status": { + "required": True, + }, + "download_queue_info": { + "required": True, + }, + "privacyAcknowledgement": { + "required": True, + }, + "dialog": { + "required": True, + }, + } + + def __init__( + self, + pings: List[float] = None, + cancel_purchase_batch: bool = None, + customerMessage: str = None, + failureType: str = None, + accountInfo: _accountInfo = None, + passwordToken: str = None, + clearToken: str = None, + m_allowed: bool = None, + is_cloud_enabled: str = None, + dsPersonId: str = None, + creditDisplay: str = None, + creditBalance: str = None, + freeSongBalance: str = None, + isManagedStudent: bool = None, + action: _action = None, + subscriptionStatus: _subscriptionStatus = None, + accountFlags: _accountFlags = None, + status: int = None, + download_queue_info: _download_queue_info = None, + privacyAcknowledgement: _privacyAcknowledgement = None, + dialog: _dialog = None, + ): + pass + self.__pings = pings + self.__cancel_purchase_batch = cancel_purchase_batch + self.__customerMessage = customerMessage + self.__failureType = failureType + self.__accountInfo = accountInfo + self.__passwordToken = passwordToken + self.__clearToken = clearToken + self.__m_allowed = m_allowed + self.__is_cloud_enabled = is_cloud_enabled + self.__dsPersonId = dsPersonId + self.__creditDisplay = creditDisplay + self.__creditBalance = creditBalance + self.__freeSongBalance = freeSongBalance + self.__isManagedStudent = isManagedStudent + self.__action = action + self.__subscriptionStatus = subscriptionStatus + self.__accountFlags = accountFlags + self.__status = status + self.__download_queue_info = download_queue_info + self.__privacyAcknowledgement = privacyAcknowledgement + self.__dialog = dialog + + def _get_pings(self): + return self.__pings + + def _set_pings(self, value): + if not isinstance(value, list): + raise TypeError("pings must be list") + if not all(isinstance(i, float) for i in value): + raise TypeError("pings list values must be float") + + self.__pings = value + + pings = property(_get_pings, _set_pings) + + def _get_cancel_purchase_batch(self): + return self.__cancel_purchase_batch + + def _set_cancel_purchase_batch(self, value): + if value is not None and not isinstance(value, bool): + raise TypeError("cancel_purchase_batch must be bool") + + self.__cancel_purchase_batch = value + + cancel_purchase_batch = property( + _get_cancel_purchase_batch, _set_cancel_purchase_batch + ) + + def _get_customerMessage(self): + return self.__customerMessage + + def _set_customerMessage(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("customerMessage must be str") + + self.__customerMessage = value + + customerMessage = property(_get_customerMessage, _set_customerMessage) + + def _get_failureType(self): + return self.__failureType + + def _set_failureType(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("failureType must be str") + + self.__failureType = value + + failureType = property(_get_failureType, _set_failureType) + + def _get_accountInfo(self): + return self.__accountInfo + + def _set_accountInfo(self, value): + if not isinstance(value, StoreAuthenticateResp._accountInfo): + raise TypeError("accountInfo must be StoreAuthenticateResp._accountInfo") + + self.__accountInfo = value + + accountInfo = property(_get_accountInfo, _set_accountInfo) + + def _get_passwordToken(self): + return self.__passwordToken + + def _set_passwordToken(self, value): + if not isinstance(value, str): + raise TypeError("passwordToken must be str") + + self.__passwordToken = value + + passwordToken = property(_get_passwordToken, _set_passwordToken) + + def _get_clearToken(self): + return self.__clearToken + + def _set_clearToken(self, value): + if not isinstance(value, str): + raise TypeError("clearToken must be str") + + self.__clearToken = value + + clearToken = property(_get_clearToken, _set_clearToken) + + def _get_m_allowed(self): + return self.__m_allowed + + def _set_m_allowed(self, value): + if not isinstance(value, bool): + raise TypeError("m_allowed must be bool") + + self.__m_allowed = value + + m_allowed = property(_get_m_allowed, _set_m_allowed) + + def _get_is_cloud_enabled(self): + return self.__is_cloud_enabled + + def _set_is_cloud_enabled(self, value): + if not isinstance(value, str): + raise TypeError("is_cloud_enabled must be str") + + self.__is_cloud_enabled = value + + is_cloud_enabled = property(_get_is_cloud_enabled, _set_is_cloud_enabled) + + def _get_dsPersonId(self): + return self.__dsPersonId + + def _set_dsPersonId(self, value): + if not isinstance(value, str): + raise TypeError("dsPersonId must be str") + + self.__dsPersonId = value + + dsPersonId = property(_get_dsPersonId, _set_dsPersonId) + + def _get_creditDisplay(self): + return self.__creditDisplay + + def _set_creditDisplay(self, value): + if not isinstance(value, str): + raise TypeError("creditDisplay must be str") + + self.__creditDisplay = value + + creditDisplay = property(_get_creditDisplay, _set_creditDisplay) + + def _get_creditBalance(self): + return self.__creditBalance + + def _set_creditBalance(self, value): + if not isinstance(value, str): + raise TypeError("creditBalance must be str") + + self.__creditBalance = value + + creditBalance = property(_get_creditBalance, _set_creditBalance) + + def _get_freeSongBalance(self): + return self.__freeSongBalance + + def _set_freeSongBalance(self, value): + if not isinstance(value, str): + raise TypeError("freeSongBalance must be str") + + self.__freeSongBalance = value + + freeSongBalance = property(_get_freeSongBalance, _set_freeSongBalance) + + def _get_isManagedStudent(self): + return self.__isManagedStudent + + def _set_isManagedStudent(self, value): + if not isinstance(value, bool): + raise TypeError("isManagedStudent must be bool") + + self.__isManagedStudent = value + + isManagedStudent = property(_get_isManagedStudent, _set_isManagedStudent) + + def _get_action(self): + return self.__action + + def _set_action(self, value): + if not isinstance(value, StoreAuthenticateResp._action): + raise TypeError("action must be StoreAuthenticateResp._action") + + self.__action = value + + action = property(_get_action, _set_action) + + def _get_subscriptionStatus(self): + return self.__subscriptionStatus + + def _set_subscriptionStatus(self, value): + if not isinstance(value, StoreAuthenticateResp._subscriptionStatus): + raise TypeError( + "subscriptionStatus must be StoreAuthenticateResp._subscriptionStatus" + ) + + self.__subscriptionStatus = value + + subscriptionStatus = property(_get_subscriptionStatus, _set_subscriptionStatus) + + def _get_accountFlags(self): + return self.__accountFlags + + def _set_accountFlags(self, value): + if not isinstance(value, StoreAuthenticateResp._accountFlags): + raise TypeError("accountFlags must be StoreAuthenticateResp._accountFlags") + + self.__accountFlags = value + + accountFlags = property(_get_accountFlags, _set_accountFlags) + + def _get_status(self): + return self.__status + + def _set_status(self, value): + if not isinstance(value, int): + raise TypeError("status must be int") + + self.__status = value + + status = property(_get_status, _set_status) + + def _get_download_queue_info(self): + return self.__download_queue_info + + def _set_download_queue_info(self, value): + if not isinstance(value, StoreAuthenticateResp._download_queue_info): + raise TypeError( + "download_queue_info must be StoreAuthenticateResp._download_queue_info" + ) + + self.__download_queue_info = value + + download_queue_info = property(_get_download_queue_info, _set_download_queue_info) + + def _get_privacyAcknowledgement(self): + return self.__privacyAcknowledgement + + def _set_privacyAcknowledgement(self, value): + if not isinstance(value, StoreAuthenticateResp._privacyAcknowledgement): + raise TypeError( + "privacyAcknowledgement must be StoreAuthenticateResp._privacyAcknowledgement" + ) + + self.__privacyAcknowledgement = value + + privacyAcknowledgement = property( + _get_privacyAcknowledgement, _set_privacyAcknowledgement + ) + + def _get_dialog(self): + return self.__dialog + + def _set_dialog(self, value): + if not isinstance(value, StoreAuthenticateResp._dialog): + raise TypeError("dialog must be StoreAuthenticateResp._dialog") + + self.__dialog = value + + dialog = property(_get_dialog, _set_dialog) + + @staticmethod + def from_dict(d): + v = {} + if "pings" in d: + v["pings"] = [ + float.from_dict(p) if hasattr(float, "from_dict") else p + for p in d["pings"] + ] + if "cancel-purchase-batch" in d: + v["cancel_purchase_batch"] = ( + bool.from_dict(d["cancel-purchase-batch"]) + if hasattr(bool, "from_dict") + else d["cancel-purchase-batch"] + ) + if "customerMessage" in d: + v["customerMessage"] = ( + str.from_dict(d["customerMessage"]) + if hasattr(str, "from_dict") + else d["customerMessage"] + ) + if "failureType" in d: + v["failureType"] = ( + str.from_dict(d["failureType"]) + if hasattr(str, "from_dict") + else d["failureType"] + ) + if "accountInfo" in d: + v["accountInfo"] = ( + StoreAuthenticateResp._accountInfo.from_dict(d["accountInfo"]) + if hasattr(StoreAuthenticateResp._accountInfo, "from_dict") + else d["accountInfo"] + ) + if "passwordToken" in d: + v["passwordToken"] = ( + str.from_dict(d["passwordToken"]) + if hasattr(str, "from_dict") + else d["passwordToken"] + ) + if "clearToken" in d: + v["clearToken"] = ( + str.from_dict(d["clearToken"]) + if hasattr(str, "from_dict") + else d["clearToken"] + ) + if "m-allowed" in d: + v["m_allowed"] = ( + bool.from_dict(d["m-allowed"]) + if hasattr(bool, "from_dict") + else d["m-allowed"] + ) + if "is-cloud-enabled" in d: + v["is_cloud_enabled"] = ( + str.from_dict(d["is-cloud-enabled"]) + if hasattr(str, "from_dict") + else d["is-cloud-enabled"] + ) + if "dsPersonId" in d: + v["dsPersonId"] = ( + str.from_dict(d["dsPersonId"]) + if hasattr(str, "from_dict") + else d["dsPersonId"] + ) + if "creditDisplay" in d: + v["creditDisplay"] = ( + str.from_dict(d["creditDisplay"]) + if hasattr(str, "from_dict") + else d["creditDisplay"] + ) + if "creditBalance" in d: + v["creditBalance"] = ( + str.from_dict(d["creditBalance"]) + if hasattr(str, "from_dict") + else d["creditBalance"] + ) + if "freeSongBalance" in d: + v["freeSongBalance"] = ( + str.from_dict(d["freeSongBalance"]) + if hasattr(str, "from_dict") + else d["freeSongBalance"] + ) + if "isManagedStudent" in d: + v["isManagedStudent"] = ( + bool.from_dict(d["isManagedStudent"]) + if hasattr(bool, "from_dict") + else d["isManagedStudent"] + ) + if "action" in d: + v["action"] = ( + StoreAuthenticateResp._action.from_dict(d["action"]) + if hasattr(StoreAuthenticateResp._action, "from_dict") + else d["action"] + ) + if "subscriptionStatus" in d: + v["subscriptionStatus"] = ( + StoreAuthenticateResp._subscriptionStatus.from_dict( + d["subscriptionStatus"] + ) + if hasattr(StoreAuthenticateResp._subscriptionStatus, "from_dict") + else d["subscriptionStatus"] + ) + if "accountFlags" in d: + v["accountFlags"] = ( + StoreAuthenticateResp._accountFlags.from_dict(d["accountFlags"]) + if hasattr(StoreAuthenticateResp._accountFlags, "from_dict") + else d["accountFlags"] + ) + if "status" in d: + v["status"] = ( + int.from_dict(d["status"]) if hasattr(int, "from_dict") else d["status"] + ) + if "download-queue-info" in d: + v["download_queue_info"] = ( + StoreAuthenticateResp._download_queue_info.from_dict( + d["download-queue-info"] + ) + if hasattr(StoreAuthenticateResp._download_queue_info, "from_dict") + else d["download-queue-info"] + ) + if "privacyAcknowledgement" in d: + v["privacyAcknowledgement"] = ( + StoreAuthenticateResp._privacyAcknowledgement.from_dict( + d["privacyAcknowledgement"] + ) + if hasattr(StoreAuthenticateResp._privacyAcknowledgement, "from_dict") + else d["privacyAcknowledgement"] + ) + if "dialog" in d: + v["dialog"] = ( + StoreAuthenticateResp._dialog.from_dict(d["dialog"]) + if hasattr(StoreAuthenticateResp._dialog, "from_dict") + else d["dialog"] + ) + return StoreAuthenticateResp(**v) + + def as_dict(self): + d = {} + if self.__pings is not None: + d["pings"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__pings + ] + if self.__cancel_purchase_batch is not None: + d["cancel-purchase-batch"] = ( + self.__cancel_purchase_batch.as_dict() + if hasattr(self.__cancel_purchase_batch, "as_dict") + else self.__cancel_purchase_batch + ) + if self.__customerMessage is not None: + d["customerMessage"] = ( + self.__customerMessage.as_dict() + if hasattr(self.__customerMessage, "as_dict") + else self.__customerMessage + ) + if self.__failureType is not None: + d["failureType"] = ( + self.__failureType.as_dict() + if hasattr(self.__failureType, "as_dict") + else self.__failureType + ) + if self.__accountInfo is not None: + d["accountInfo"] = ( + self.__accountInfo.as_dict() + if hasattr(self.__accountInfo, "as_dict") + else self.__accountInfo + ) + if self.__passwordToken is not None: + d["passwordToken"] = ( + self.__passwordToken.as_dict() + if hasattr(self.__passwordToken, "as_dict") + else self.__passwordToken + ) + if self.__clearToken is not None: + d["clearToken"] = ( + self.__clearToken.as_dict() + if hasattr(self.__clearToken, "as_dict") + else self.__clearToken + ) + if self.__m_allowed is not None: + d["m-allowed"] = ( + self.__m_allowed.as_dict() + if hasattr(self.__m_allowed, "as_dict") + else self.__m_allowed + ) + if self.__is_cloud_enabled is not None: + d["is-cloud-enabled"] = ( + self.__is_cloud_enabled.as_dict() + if hasattr(self.__is_cloud_enabled, "as_dict") + else self.__is_cloud_enabled + ) + if self.__dsPersonId is not None: + d["dsPersonId"] = ( + self.__dsPersonId.as_dict() + if hasattr(self.__dsPersonId, "as_dict") + else self.__dsPersonId + ) + if self.__creditDisplay is not None: + d["creditDisplay"] = ( + self.__creditDisplay.as_dict() + if hasattr(self.__creditDisplay, "as_dict") + else self.__creditDisplay + ) + if self.__creditBalance is not None: + d["creditBalance"] = ( + self.__creditBalance.as_dict() + if hasattr(self.__creditBalance, "as_dict") + else self.__creditBalance + ) + if self.__freeSongBalance is not None: + d["freeSongBalance"] = ( + self.__freeSongBalance.as_dict() + if hasattr(self.__freeSongBalance, "as_dict") + else self.__freeSongBalance + ) + if self.__isManagedStudent is not None: + d["isManagedStudent"] = ( + self.__isManagedStudent.as_dict() + if hasattr(self.__isManagedStudent, "as_dict") + else self.__isManagedStudent + ) + if self.__action is not None: + d["action"] = ( + self.__action.as_dict() + if hasattr(self.__action, "as_dict") + else self.__action + ) + if self.__subscriptionStatus is not None: + d["subscriptionStatus"] = ( + self.__subscriptionStatus.as_dict() + if hasattr(self.__subscriptionStatus, "as_dict") + else self.__subscriptionStatus + ) + if self.__accountFlags is not None: + d["accountFlags"] = ( + self.__accountFlags.as_dict() + if hasattr(self.__accountFlags, "as_dict") + else self.__accountFlags + ) + if self.__status is not None: + d["status"] = ( + self.__status.as_dict() + if hasattr(self.__status, "as_dict") + else self.__status + ) + if self.__download_queue_info is not None: + d["download-queue-info"] = ( + self.__download_queue_info.as_dict() + if hasattr(self.__download_queue_info, "as_dict") + else self.__download_queue_info + ) + if self.__privacyAcknowledgement is not None: + d["privacyAcknowledgement"] = ( + self.__privacyAcknowledgement.as_dict() + if hasattr(self.__privacyAcknowledgement, "as_dict") + else self.__privacyAcknowledgement + ) + if self.__dialog is not None: + d["dialog"] = ( + self.__dialog.as_dict() + if hasattr(self.__dialog, "as_dict") + else self.__dialog + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__pings[:20] if isinstance(self.__pings, bytes) else self.__pings + ), + limitedRepr( + self.__cancel_purchase_batch[:20] + if isinstance(self.__cancel_purchase_batch, bytes) + else self.__cancel_purchase_batch + ), + limitedRepr( + self.__customerMessage[:20] + if isinstance(self.__customerMessage, bytes) + else self.__customerMessage + ), + limitedRepr( + self.__failureType[:20] + if isinstance(self.__failureType, bytes) + else self.__failureType + ), + limitedRepr( + self.__accountInfo[:20] + if isinstance(self.__accountInfo, bytes) + else self.__accountInfo + ), + limitedRepr( + self.__passwordToken[:20] + if isinstance(self.__passwordToken, bytes) + else self.__passwordToken + ), + limitedRepr( + self.__clearToken[:20] + if isinstance(self.__clearToken, bytes) + else self.__clearToken + ), + limitedRepr( + self.__m_allowed[:20] + if isinstance(self.__m_allowed, bytes) + else self.__m_allowed + ), + limitedRepr( + self.__is_cloud_enabled[:20] + if isinstance(self.__is_cloud_enabled, bytes) + else self.__is_cloud_enabled + ), + limitedRepr( + self.__dsPersonId[:20] + if isinstance(self.__dsPersonId, bytes) + else self.__dsPersonId + ), + limitedRepr( + self.__creditDisplay[:20] + if isinstance(self.__creditDisplay, bytes) + else self.__creditDisplay + ), + limitedRepr( + self.__creditBalance[:20] + if isinstance(self.__creditBalance, bytes) + else self.__creditBalance + ), + limitedRepr( + self.__freeSongBalance[:20] + if isinstance(self.__freeSongBalance, bytes) + else self.__freeSongBalance + ), + limitedRepr( + self.__isManagedStudent[:20] + if isinstance(self.__isManagedStudent, bytes) + else self.__isManagedStudent + ), + limitedRepr( + self.__action[:20] + if isinstance(self.__action, bytes) + else self.__action + ), + limitedRepr( + self.__subscriptionStatus[:20] + if isinstance(self.__subscriptionStatus, bytes) + else self.__subscriptionStatus + ), + limitedRepr( + self.__accountFlags[:20] + if isinstance(self.__accountFlags, bytes) + else self.__accountFlags + ), + limitedRepr( + self.__status[:20] + if isinstance(self.__status, bytes) + else self.__status + ), + limitedRepr( + self.__download_queue_info[:20] + if isinstance(self.__download_queue_info, bytes) + else self.__download_queue_info + ), + limitedRepr( + self.__privacyAcknowledgement[:20] + if isinstance(self.__privacyAcknowledgement, bytes) + else self.__privacyAcknowledgement + ), + limitedRepr( + self.__dialog[:20] + if isinstance(self.__dialog, bytes) + else self.__dialog + ), + ) diff --git a/src_mac/ipatool-py/reqs/schemas/store_buyproduct_req.py b/src_mac/ipatool-py/reqs/schemas/store_buyproduct_req.py new file mode 100755 index 0000000..064c02f --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/store_buyproduct_req.py @@ -0,0 +1,956 @@ +from reprlib import repr as limitedRepr + + +class StoreBuyproductReq: + + _types_map = { + "ageCheck": {"type": str, "subtype": None}, + "appExtVrsId": {"type": str, "subtype": None}, + "guid": {"type": str, "subtype": None}, + "hasBeenAuthedForBuy": {"type": str, "subtype": None}, + "isInApp": {"type": str, "subtype": None}, + "kbsync": {"type": str, "subtype": None}, + "sbsync": {"type": str, "subtype": None}, + "afds": {"type": str, "subtype": None}, + "machineName": {"type": str, "subtype": None}, + "mtApp": {"type": str, "subtype": None}, + "mtClientId": {"type": str, "subtype": None}, + "mtEventTime": {"type": str, "subtype": None}, + "mtPageId": {"type": str, "subtype": None}, + "mtPageType": {"type": str, "subtype": None}, + "mtPrevPage": {"type": str, "subtype": None}, + "mtRequestId": {"type": str, "subtype": None}, + "mtTopic": {"type": str, "subtype": None}, + "needDiv": {"type": str, "subtype": None}, + "pg": {"type": str, "subtype": None}, + "price": {"type": str, "subtype": None}, + "pricingParameters": {"type": str, "subtype": None}, + "productType": {"type": str, "subtype": None}, + "salableAdamId": {"type": str, "subtype": None}, + "hasAskedToFulfillPreorder": {"type": str, "subtype": None}, + "buyWithoutAuthorization": {"type": str, "subtype": None}, + "hasDoneAgeCheck": {"type": str, "subtype": None}, + "hasConfirmedPaymentSheet": {"type": str, "subtype": None}, + "asn": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "ageCheck": { + "required": False, + }, + "appExtVrsId": { + "required": True, + }, + "guid": { + "required": True, + }, + "hasBeenAuthedForBuy": { + "required": False, + }, + "isInApp": { + "required": False, + }, + "kbsync": { + "required": True, + }, + "sbsync": { + "required": False, + }, + "afds": { + "required": False, + }, + "machineName": { + "required": False, + }, + "mtApp": { + "required": False, + }, + "mtClientId": { + "required": False, + }, + "mtEventTime": { + "required": False, + }, + "mtPageId": { + "required": False, + }, + "mtPageType": { + "required": False, + }, + "mtPrevPage": { + "required": False, + }, + "mtRequestId": { + "required": False, + }, + "mtTopic": { + "required": False, + }, + "needDiv": { + "required": False, + }, + "pg": { + "required": False, + }, + "price": { + "required": True, + }, + "pricingParameters": { + "required": True, + }, + "productType": { + "required": True, + }, + "salableAdamId": { + "required": True, + }, + "hasAskedToFulfillPreorder": { + "required": False, + }, + "buyWithoutAuthorization": { + "required": False, + }, + "hasDoneAgeCheck": { + "required": False, + }, + "hasConfirmedPaymentSheet": { + "required": False, + }, + "asn": { + "required": False, + }, + } + + def __init__( + self, + ageCheck: str = None, + appExtVrsId: str = None, + guid: str = None, + hasBeenAuthedForBuy: str = None, + isInApp: str = None, + kbsync: str = None, + sbsync: str = None, + afds: str = None, + machineName: str = None, + mtApp: str = None, + mtClientId: str = None, + mtEventTime: str = None, + mtPageId: str = None, + mtPageType: str = None, + mtPrevPage: str = None, + mtRequestId: str = None, + mtTopic: str = None, + needDiv: str = None, + pg: str = None, + price: str = None, + pricingParameters: str = None, + productType: str = None, + salableAdamId: str = None, + hasAskedToFulfillPreorder: str = None, + buyWithoutAuthorization: str = None, + hasDoneAgeCheck: str = None, + hasConfirmedPaymentSheet: str = None, + asn: str = None, + ): + pass + self.__ageCheck = ageCheck + self.__appExtVrsId = appExtVrsId + self.__guid = guid + self.__hasBeenAuthedForBuy = hasBeenAuthedForBuy + self.__isInApp = isInApp + self.__kbsync = kbsync + self.__sbsync = sbsync + self.__afds = afds + self.__machineName = machineName + self.__mtApp = mtApp + self.__mtClientId = mtClientId + self.__mtEventTime = mtEventTime + self.__mtPageId = mtPageId + self.__mtPageType = mtPageType + self.__mtPrevPage = mtPrevPage + self.__mtRequestId = mtRequestId + self.__mtTopic = mtTopic + self.__needDiv = needDiv + self.__pg = pg + self.__price = price + self.__pricingParameters = pricingParameters + self.__productType = productType + self.__salableAdamId = salableAdamId + self.__hasAskedToFulfillPreorder = hasAskedToFulfillPreorder + self.__buyWithoutAuthorization = buyWithoutAuthorization + self.__hasDoneAgeCheck = hasDoneAgeCheck + self.__hasConfirmedPaymentSheet = hasConfirmedPaymentSheet + self.__asn = asn + + def _get_ageCheck(self): + return self.__ageCheck + + def _set_ageCheck(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("ageCheck must be str") + + self.__ageCheck = value + + ageCheck = property(_get_ageCheck, _set_ageCheck) + + def _get_appExtVrsId(self): + return self.__appExtVrsId + + def _set_appExtVrsId(self, value): + if not isinstance(value, str): + raise TypeError("appExtVrsId must be str") + + self.__appExtVrsId = value + + appExtVrsId = property(_get_appExtVrsId, _set_appExtVrsId) + + def _get_guid(self): + return self.__guid + + def _set_guid(self, value): + if not isinstance(value, str): + raise TypeError("guid must be str") + + self.__guid = value + + guid = property(_get_guid, _set_guid) + + def _get_hasBeenAuthedForBuy(self): + return self.__hasBeenAuthedForBuy + + def _set_hasBeenAuthedForBuy(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("hasBeenAuthedForBuy must be str") + + self.__hasBeenAuthedForBuy = value + + hasBeenAuthedForBuy = property(_get_hasBeenAuthedForBuy, _set_hasBeenAuthedForBuy) + + def _get_isInApp(self): + return self.__isInApp + + def _set_isInApp(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("isInApp must be str") + + self.__isInApp = value + + isInApp = property(_get_isInApp, _set_isInApp) + + def _get_kbsync(self): + return self.__kbsync + + def _set_kbsync(self, value): + if not isinstance(value, str): + raise TypeError("kbsync must be str") + + self.__kbsync = value + + kbsync = property(_get_kbsync, _set_kbsync) + + def _get_sbsync(self): + return self.__sbsync + + def _set_sbsync(self, value): + if not isinstance(value, str): + raise TypeError("sbsync must be str") + + self.__sbsync = value + + sbsync = property(_get_sbsync, _set_sbsync) + + def _get_afds(self): + return self.__afds + + def _set_afds(self, value): + if not isinstance(value, str): + raise TypeError("afds must be str") + + self.__afds = value + + afds = property(_get_afds, _set_afds) + + def _get_machineName(self): + return self.__machineName + + def _set_machineName(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("machineName must be str") + + self.__machineName = value + + machineName = property(_get_machineName, _set_machineName) + + def _get_mtApp(self): + return self.__mtApp + + def _set_mtApp(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("mtApp must be str") + + self.__mtApp = value + + mtApp = property(_get_mtApp, _set_mtApp) + + def _get_mtClientId(self): + return self.__mtClientId + + def _set_mtClientId(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("mtClientId must be str") + + self.__mtClientId = value + + mtClientId = property(_get_mtClientId, _set_mtClientId) + + def _get_mtEventTime(self): + return self.__mtEventTime + + def _set_mtEventTime(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("mtEventTime must be str") + + self.__mtEventTime = value + + mtEventTime = property(_get_mtEventTime, _set_mtEventTime) + + def _get_mtPageId(self): + return self.__mtPageId + + def _set_mtPageId(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("mtPageId must be str") + + self.__mtPageId = value + + mtPageId = property(_get_mtPageId, _set_mtPageId) + + def _get_mtPageType(self): + return self.__mtPageType + + def _set_mtPageType(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("mtPageType must be str") + + self.__mtPageType = value + + mtPageType = property(_get_mtPageType, _set_mtPageType) + + def _get_mtPrevPage(self): + return self.__mtPrevPage + + def _set_mtPrevPage(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("mtPrevPage must be str") + + self.__mtPrevPage = value + + mtPrevPage = property(_get_mtPrevPage, _set_mtPrevPage) + + def _get_mtRequestId(self): + return self.__mtRequestId + + def _set_mtRequestId(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("mtRequestId must be str") + + self.__mtRequestId = value + + mtRequestId = property(_get_mtRequestId, _set_mtRequestId) + + def _get_mtTopic(self): + return self.__mtTopic + + def _set_mtTopic(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("mtTopic must be str") + + self.__mtTopic = value + + mtTopic = property(_get_mtTopic, _set_mtTopic) + + def _get_needDiv(self): + return self.__needDiv + + def _set_needDiv(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("needDiv must be str") + + self.__needDiv = value + + needDiv = property(_get_needDiv, _set_needDiv) + + def _get_pg(self): + return self.__pg + + def _set_pg(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("pg must be str") + + self.__pg = value + + pg = property(_get_pg, _set_pg) + + def _get_price(self): + return self.__price + + def _set_price(self, value): + if not isinstance(value, str): + raise TypeError("price must be str") + + self.__price = value + + price = property(_get_price, _set_price) + + def _get_pricingParameters(self): + return self.__pricingParameters + + def _set_pricingParameters(self, value): + if not isinstance(value, str): + raise TypeError("pricingParameters must be str") + + self.__pricingParameters = value + + pricingParameters = property(_get_pricingParameters, _set_pricingParameters) + + def _get_productType(self): + return self.__productType + + def _set_productType(self, value): + if not isinstance(value, str): + raise TypeError("productType must be str") + + self.__productType = value + + productType = property(_get_productType, _set_productType) + + def _get_salableAdamId(self): + return self.__salableAdamId + + def _set_salableAdamId(self, value): + if not isinstance(value, str): + raise TypeError("salableAdamId must be str") + + self.__salableAdamId = value + + salableAdamId = property(_get_salableAdamId, _set_salableAdamId) + + def _get_hasAskedToFulfillPreorder(self): + return self.__hasAskedToFulfillPreorder + + def _set_hasAskedToFulfillPreorder(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("hasAskedToFulfillPreorder must be str") + + self.__hasAskedToFulfillPreorder = value + + hasAskedToFulfillPreorder = property( + _get_hasAskedToFulfillPreorder, _set_hasAskedToFulfillPreorder + ) + + def _get_buyWithoutAuthorization(self): + return self.__buyWithoutAuthorization + + def _set_buyWithoutAuthorization(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("buyWithoutAuthorization must be str") + + self.__buyWithoutAuthorization = value + + buyWithoutAuthorization = property( + _get_buyWithoutAuthorization, _set_buyWithoutAuthorization + ) + + def _get_hasDoneAgeCheck(self): + return self.__hasDoneAgeCheck + + def _set_hasDoneAgeCheck(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("hasDoneAgeCheck must be str") + + self.__hasDoneAgeCheck = value + + hasDoneAgeCheck = property(_get_hasDoneAgeCheck, _set_hasDoneAgeCheck) + + def _get_hasConfirmedPaymentSheet(self): + return self.__hasConfirmedPaymentSheet + + def _set_hasConfirmedPaymentSheet(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("hasConfirmedPaymentSheet must be str") + + self.__hasConfirmedPaymentSheet = value + + hasConfirmedPaymentSheet = property(_get_hasConfirmedPaymentSheet, _set_hasConfirmedPaymentSheet) + + def _get_asn(self): + return self.__asn + + def _set_asn(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("asn must be str") + + self.__asn = value + + asn = property(_get_asn, _set_asn) + + @staticmethod + def from_dict(d): + v = {} + if "ageCheck" in d: + v["ageCheck"] = ( + str.from_dict(d["ageCheck"]) + if hasattr(str, "from_dict") + else d["ageCheck"] + ) + if "appExtVrsId" in d: + v["appExtVrsId"] = ( + str.from_dict(d["appExtVrsId"]) + if hasattr(str, "from_dict") + else d["appExtVrsId"] + ) + if "guid" in d: + v["guid"] = ( + str.from_dict(d["guid"]) if hasattr(str, "from_dict") else d["guid"] + ) + if "hasBeenAuthedForBuy" in d: + v["hasBeenAuthedForBuy"] = ( + str.from_dict(d["hasBeenAuthedForBuy"]) + if hasattr(str, "from_dict") + else d["hasBeenAuthedForBuy"] + ) + if "isInApp" in d: + v["isInApp"] = ( + str.from_dict(d["isInApp"]) + if hasattr(str, "from_dict") + else d["isInApp"] + ) + if "kbsync" in d: + v["kbsync"] = ( + str.from_dict(d["kbsync"]) if hasattr(str, "from_dict") else d["kbsync"] + ) + if "sbsync" in d: + v["sbsync"] = ( + str.from_dict(d["sbsync"]) if hasattr(str, "from_dict") else d["sbsync"] + ) + if "afds" in d: + v["afds"] = ( + str.from_dict(d["afds"]) if hasattr(str, "from_dict") else d["afds"] + ) + if "machineName" in d: + v["machineName"] = ( + str.from_dict(d["machineName"]) + if hasattr(str, "from_dict") + else d["machineName"] + ) + if "mtApp" in d: + v["mtApp"] = ( + str.from_dict(d["mtApp"]) if hasattr(str, "from_dict") else d["mtApp"] + ) + if "mtClientId" in d: + v["mtClientId"] = ( + str.from_dict(d["mtClientId"]) + if hasattr(str, "from_dict") + else d["mtClientId"] + ) + if "mtEventTime" in d: + v["mtEventTime"] = ( + str.from_dict(d["mtEventTime"]) + if hasattr(str, "from_dict") + else d["mtEventTime"] + ) + if "mtPageId" in d: + v["mtPageId"] = ( + str.from_dict(d["mtPageId"]) + if hasattr(str, "from_dict") + else d["mtPageId"] + ) + if "mtPageType" in d: + v["mtPageType"] = ( + str.from_dict(d["mtPageType"]) + if hasattr(str, "from_dict") + else d["mtPageType"] + ) + if "mtPrevPage" in d: + v["mtPrevPage"] = ( + str.from_dict(d["mtPrevPage"]) + if hasattr(str, "from_dict") + else d["mtPrevPage"] + ) + if "mtRequestId" in d: + v["mtRequestId"] = ( + str.from_dict(d["mtRequestId"]) + if hasattr(str, "from_dict") + else d["mtRequestId"] + ) + if "mtTopic" in d: + v["mtTopic"] = ( + str.from_dict(d["mtTopic"]) + if hasattr(str, "from_dict") + else d["mtTopic"] + ) + if "needDiv" in d: + v["needDiv"] = ( + str.from_dict(d["needDiv"]) + if hasattr(str, "from_dict") + else d["needDiv"] + ) + if "pg" in d: + v["pg"] = str.from_dict(d["pg"]) if hasattr(str, "from_dict") else d["pg"] + if "price" in d: + v["price"] = ( + str.from_dict(d["price"]) if hasattr(str, "from_dict") else d["price"] + ) + if "pricingParameters" in d: + v["pricingParameters"] = ( + str.from_dict(d["pricingParameters"]) + if hasattr(str, "from_dict") + else d["pricingParameters"] + ) + if "productType" in d: + v["productType"] = ( + str.from_dict(d["productType"]) + if hasattr(str, "from_dict") + else d["productType"] + ) + if "salableAdamId" in d: + v["salableAdamId"] = ( + str.from_dict(d["salableAdamId"]) + if hasattr(str, "from_dict") + else d["salableAdamId"] + ) + if "hasAskedToFulfillPreorder" in d: + v["hasAskedToFulfillPreorder"] = ( + str.from_dict(d["hasAskedToFulfillPreorder"]) + if hasattr(str, "from_dict") + else d["hasAskedToFulfillPreorder"] + ) + if "buyWithoutAuthorization" in d: + v["buyWithoutAuthorization"] = ( + str.from_dict(d["buyWithoutAuthorization"]) + if hasattr(str, "from_dict") + else d["buyWithoutAuthorization"] + ) + if "hasDoneAgeCheck" in d: + v["hasDoneAgeCheck"] = ( + str.from_dict(d["hasDoneAgeCheck"]) + if hasattr(str, "from_dict") + else d["hasDoneAgeCheck"] + ) + if "hasConfirmedPaymentSheet" in d: + v["hasConfirmedPaymentSheet"] = ( + str.from_dict(d["hasConfirmedPaymentSheet"]) + if hasattr(str, "from_dict") + else d["hasConfirmedPaymentSheet"] + ) + if "asn" in d: + v["asn"] = ( + str.from_dict(d["asn"]) + if hasattr(str, "from_dict") + else d["asn"] + ) + return StoreBuyproductReq(**v) + + def as_dict(self): + d = {} + if self.__ageCheck is not None: + d["ageCheck"] = ( + self.__ageCheck.as_dict() + if hasattr(self.__ageCheck, "as_dict") + else self.__ageCheck + ) + if self.__appExtVrsId is not None: + d["appExtVrsId"] = ( + self.__appExtVrsId.as_dict() + if hasattr(self.__appExtVrsId, "as_dict") + else self.__appExtVrsId + ) + if self.__guid is not None: + d["guid"] = ( + self.__guid.as_dict() + if hasattr(self.__guid, "as_dict") + else self.__guid + ) + if self.__hasBeenAuthedForBuy is not None: + d["hasBeenAuthedForBuy"] = ( + self.__hasBeenAuthedForBuy.as_dict() + if hasattr(self.__hasBeenAuthedForBuy, "as_dict") + else self.__hasBeenAuthedForBuy + ) + if self.__isInApp is not None: + d["isInApp"] = ( + self.__isInApp.as_dict() + if hasattr(self.__isInApp, "as_dict") + else self.__isInApp + ) + if self.__kbsync is not None: + d["kbsync"] = ( + self.__kbsync.as_dict() + if hasattr(self.__kbsync, "as_dict") + else self.__kbsync + ) + if self.__sbsync is not None: + d["sbsync"] = ( + self.__sbsync.as_dict() + if hasattr(self.__sbsync, "as_dict") + else self.__sbsync + ) + if self.__afds is not None: + d["afds"] = ( + self.__afds.as_dict() + if hasattr(self.__afds, "as_dict") + else self.__afds + ) + if self.__machineName is not None: + d["machineName"] = ( + self.__machineName.as_dict() + if hasattr(self.__machineName, "as_dict") + else self.__machineName + ) + if self.__mtApp is not None: + d["mtApp"] = ( + self.__mtApp.as_dict() + if hasattr(self.__mtApp, "as_dict") + else self.__mtApp + ) + if self.__mtClientId is not None: + d["mtClientId"] = ( + self.__mtClientId.as_dict() + if hasattr(self.__mtClientId, "as_dict") + else self.__mtClientId + ) + if self.__mtEventTime is not None: + d["mtEventTime"] = ( + self.__mtEventTime.as_dict() + if hasattr(self.__mtEventTime, "as_dict") + else self.__mtEventTime + ) + if self.__mtPageId is not None: + d["mtPageId"] = ( + self.__mtPageId.as_dict() + if hasattr(self.__mtPageId, "as_dict") + else self.__mtPageId + ) + if self.__mtPageType is not None: + d["mtPageType"] = ( + self.__mtPageType.as_dict() + if hasattr(self.__mtPageType, "as_dict") + else self.__mtPageType + ) + if self.__mtPrevPage is not None: + d["mtPrevPage"] = ( + self.__mtPrevPage.as_dict() + if hasattr(self.__mtPrevPage, "as_dict") + else self.__mtPrevPage + ) + if self.__mtRequestId is not None: + d["mtRequestId"] = ( + self.__mtRequestId.as_dict() + if hasattr(self.__mtRequestId, "as_dict") + else self.__mtRequestId + ) + if self.__mtTopic is not None: + d["mtTopic"] = ( + self.__mtTopic.as_dict() + if hasattr(self.__mtTopic, "as_dict") + else self.__mtTopic + ) + if self.__needDiv is not None: + d["needDiv"] = ( + self.__needDiv.as_dict() + if hasattr(self.__needDiv, "as_dict") + else self.__needDiv + ) + if self.__pg is not None: + d["pg"] = ( + self.__pg.as_dict() if hasattr(self.__pg, "as_dict") else self.__pg + ) + if self.__price is not None: + d["price"] = ( + self.__price.as_dict() + if hasattr(self.__price, "as_dict") + else self.__price + ) + if self.__pricingParameters is not None: + d["pricingParameters"] = ( + self.__pricingParameters.as_dict() + if hasattr(self.__pricingParameters, "as_dict") + else self.__pricingParameters + ) + if self.__productType is not None: + d["productType"] = ( + self.__productType.as_dict() + if hasattr(self.__productType, "as_dict") + else self.__productType + ) + if self.__salableAdamId is not None: + d["salableAdamId"] = ( + self.__salableAdamId.as_dict() + if hasattr(self.__salableAdamId, "as_dict") + else self.__salableAdamId + ) + if self.__hasAskedToFulfillPreorder is not None: + d["hasAskedToFulfillPreorder"] = ( + self.__hasAskedToFulfillPreorder.as_dict() + if hasattr(self.__hasAskedToFulfillPreorder, "as_dict") + else self.__hasAskedToFulfillPreorder + ) + if self.__buyWithoutAuthorization is not None: + d["buyWithoutAuthorization"] = ( + self.__buyWithoutAuthorization.as_dict() + if hasattr(self.__buyWithoutAuthorization, "as_dict") + else self.__buyWithoutAuthorization + ) + if self.__hasDoneAgeCheck is not None: + d["hasDoneAgeCheck"] = ( + self.__hasDoneAgeCheck.as_dict() + if hasattr(self.__hasDoneAgeCheck, "as_dict") + else self.__hasDoneAgeCheck + ) + if self.__hasConfirmedPaymentSheet is not None: + d["hasConfirmedPaymentSheet"] = ( + self.__hasConfirmedPaymentSheet.as_dict() + if hasattr(self.__hasConfirmedPaymentSheet, "as_dict") + else self.__hasConfirmedPaymentSheet + ) + if self.__asn is not None: + d["asn"] = ( + self.__asn.as_dict() + if hasattr(self.__asn, "as_dict") + else self.__asn + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__ageCheck[:20] + if isinstance(self.__ageCheck, bytes) + else self.__ageCheck + ), + limitedRepr( + self.__appExtVrsId[:20] + if isinstance(self.__appExtVrsId, bytes) + else self.__appExtVrsId + ), + limitedRepr( + self.__guid[:20] if isinstance(self.__guid, bytes) else self.__guid + ), + limitedRepr( + self.__hasBeenAuthedForBuy[:20] + if isinstance(self.__hasBeenAuthedForBuy, bytes) + else self.__hasBeenAuthedForBuy + ), + limitedRepr( + self.__isInApp[:20] + if isinstance(self.__isInApp, bytes) + else self.__isInApp + ), + limitedRepr( + self.__kbsync[:20] + if isinstance(self.__kbsync, bytes) + else self.__kbsync + ), + limitedRepr( + self.__sbsync[:20] + if isinstance(self.__sbsync, bytes) + else self.__sbsync + ), + limitedRepr( + self.__afds[:20] + if isinstance(self.__afds, bytes) + else self.__afds + ), + limitedRepr( + self.__machineName[:20] + if isinstance(self.__machineName, bytes) + else self.__machineName + ), + limitedRepr( + self.__mtApp[:20] if isinstance(self.__mtApp, bytes) else self.__mtApp + ), + limitedRepr( + self.__mtClientId[:20] + if isinstance(self.__mtClientId, bytes) + else self.__mtClientId + ), + limitedRepr( + self.__mtEventTime[:20] + if isinstance(self.__mtEventTime, bytes) + else self.__mtEventTime + ), + limitedRepr( + self.__mtPageId[:20] + if isinstance(self.__mtPageId, bytes) + else self.__mtPageId + ), + limitedRepr( + self.__mtPageType[:20] + if isinstance(self.__mtPageType, bytes) + else self.__mtPageType + ), + limitedRepr( + self.__mtPrevPage[:20] + if isinstance(self.__mtPrevPage, bytes) + else self.__mtPrevPage + ), + limitedRepr( + self.__mtRequestId[:20] + if isinstance(self.__mtRequestId, bytes) + else self.__mtRequestId + ), + limitedRepr( + self.__mtTopic[:20] + if isinstance(self.__mtTopic, bytes) + else self.__mtTopic + ), + limitedRepr( + self.__needDiv[:20] + if isinstance(self.__needDiv, bytes) + else self.__needDiv + ), + limitedRepr(self.__pg[:20] if isinstance(self.__pg, bytes) else self.__pg), + limitedRepr( + self.__price[:20] if isinstance(self.__price, bytes) else self.__price + ), + limitedRepr( + self.__pricingParameters[:20] + if isinstance(self.__pricingParameters, bytes) + else self.__pricingParameters + ), + limitedRepr( + self.__productType[:20] + if isinstance(self.__productType, bytes) + else self.__productType + ), + limitedRepr( + self.__salableAdamId[:20] + if isinstance(self.__salableAdamId, bytes) + else self.__salableAdamId + ), + limitedRepr( + self.__hasAskedToFulfillPreorder[:20] + if isinstance(self.__hasAskedToFulfillPreorder, bytes) + else self.__hasAskedToFulfillPreorder + ), + limitedRepr( + self.__buyWithoutAuthorization[:20] + if isinstance(self.__buyWithoutAuthorization, bytes) + else self.__buyWithoutAuthorization + ), + limitedRepr( + self.__hasDoneAgeCheck[:20] + if isinstance(self.__hasDoneAgeCheck, bytes) + else self.__hasDoneAgeCheck + ), + limitedRepr( + self.__hasConfirmedPaymentSheet[:20] + if isinstance(self.__hasConfirmedPaymentSheet, bytes) + else self.__hasConfirmedPaymentSheet + ), + limitedRepr( + self.__asn[:20] + if isinstance(self.__asn, bytes) + else self.__asn + ), + ) diff --git a/src_mac/ipatool-py/reqs/schemas/store_buyproduct_resp.py b/src_mac/ipatool-py/reqs/schemas/store_buyproduct_resp.py new file mode 100755 index 0000000..ecf0003 --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/store_buyproduct_resp.py @@ -0,0 +1,5758 @@ +from reprlib import repr as limitedRepr + + +from typing import List + + +class StoreBuyproductResp: + class _dialog: + class _okButtonAction: + + _types_map = { + "kind": {"type": str, "subtype": None}, + "buyParams": {"type": str, "subtype": None}, + "itemName": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "kind": { + "required": True, + }, + "buyParams": { + "required": True, + }, + "itemName": { + "required": True, + }, + } + + def __init__( + self, kind: str = None, buyParams: str = None, itemName: str = None + ): + pass + self.__kind = kind + self.__buyParams = buyParams + self.__itemName = itemName + + def _get_kind(self): + return self.__kind + + def _set_kind(self, value): + if not isinstance(value, str): + raise TypeError("kind must be str") + + self.__kind = value + + kind = property(_get_kind, _set_kind) + + def _get_buyParams(self): + return self.__buyParams + + def _set_buyParams(self, value): + if not isinstance(value, str): + raise TypeError("buyParams must be str") + + self.__buyParams = value + + buyParams = property(_get_buyParams, _set_buyParams) + + def _get_itemName(self): + return self.__itemName + + def _set_itemName(self, value): + if not isinstance(value, str): + raise TypeError("itemName must be str") + + self.__itemName = value + + itemName = property(_get_itemName, _set_itemName) + + @staticmethod + def from_dict(d): + v = {} + if "kind" in d: + v["kind"] = ( + str.from_dict(d["kind"]) + if hasattr(str, "from_dict") + else d["kind"] + ) + if "buyParams" in d: + v["buyParams"] = ( + str.from_dict(d["buyParams"]) + if hasattr(str, "from_dict") + else d["buyParams"] + ) + if "itemName" in d: + v["itemName"] = ( + str.from_dict(d["itemName"]) + if hasattr(str, "from_dict") + else d["itemName"] + ) + return StoreBuyproductResp._dialog._okButtonAction(**v) + + def as_dict(self): + d = {} + if self.__kind is not None: + d["kind"] = ( + self.__kind.as_dict() + if hasattr(self.__kind, "as_dict") + else self.__kind + ) + if self.__buyParams is not None: + d["buyParams"] = ( + self.__buyParams.as_dict() + if hasattr(self.__buyParams, "as_dict") + else self.__buyParams + ) + if self.__itemName is not None: + d["itemName"] = ( + self.__itemName.as_dict() + if hasattr(self.__itemName, "as_dict") + else self.__itemName + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__kind[:20] + if isinstance(self.__kind, bytes) + else self.__kind + ), + limitedRepr( + self.__buyParams[:20] + if isinstance(self.__buyParams, bytes) + else self.__buyParams + ), + limitedRepr( + self.__itemName[:20] + if isinstance(self.__itemName, bytes) + else self.__itemName + ), + ) + + _types_map = { + "kind": {"type": str, "subtype": None}, + "m_allowed": {"type": bool, "subtype": None}, + "use_keychain": {"type": bool, "subtype": None}, + "isFree": {"type": bool, "subtype": None}, + "message": {"type": str, "subtype": None}, + "explanation": {"type": str, "subtype": None}, + "defaultButton": {"type": str, "subtype": None}, + "okButtonString": {"type": str, "subtype": None}, + "okButtonAction": {"type": _okButtonAction, "subtype": None}, + "cancelButtonString": {"type": str, "subtype": None}, + "initialCheckboxValue": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "kind": { + "required": True, + }, + "m_allowed": { + "required": True, + }, + "use_keychain": { + "required": True, + }, + "isFree": { + "required": True, + }, + "message": { + "required": True, + }, + "explanation": { + "required": True, + }, + "defaultButton": { + "required": True, + }, + "okButtonString": { + "required": True, + }, + "okButtonAction": { + "required": True, + }, + "cancelButtonString": { + "required": True, + }, + "initialCheckboxValue": { + "required": True, + }, + } + + def __init__( + self, + kind: str = None, + m_allowed: bool = None, + use_keychain: bool = None, + isFree: bool = None, + message: str = None, + explanation: str = None, + defaultButton: str = None, + okButtonString: str = None, + okButtonAction: _okButtonAction = None, + cancelButtonString: str = None, + initialCheckboxValue: bool = None, + ): + pass + self.__kind = kind + self.__m_allowed = m_allowed + self.__use_keychain = use_keychain + self.__isFree = isFree + self.__message = message + self.__explanation = explanation + self.__defaultButton = defaultButton + self.__okButtonString = okButtonString + self.__okButtonAction = okButtonAction + self.__cancelButtonString = cancelButtonString + self.__initialCheckboxValue = initialCheckboxValue + + def _get_kind(self): + return self.__kind + + def _set_kind(self, value): + if not isinstance(value, str): + raise TypeError("kind must be str") + + self.__kind = value + + kind = property(_get_kind, _set_kind) + + def _get_m_allowed(self): + return self.__m_allowed + + def _set_m_allowed(self, value): + if not isinstance(value, bool): + raise TypeError("m_allowed must be bool") + + self.__m_allowed = value + + m_allowed = property(_get_m_allowed, _set_m_allowed) + + def _get_use_keychain(self): + return self.__use_keychain + + def _set_use_keychain(self, value): + if not isinstance(value, bool): + raise TypeError("use_keychain must be bool") + + self.__use_keychain = value + + use_keychain = property(_get_use_keychain, _set_use_keychain) + + def _get_isFree(self): + return self.__isFree + + def _set_isFree(self, value): + if not isinstance(value, bool): + raise TypeError("isFree must be bool") + + self.__isFree = value + + isFree = property(_get_isFree, _set_isFree) + + def _get_message(self): + return self.__message + + def _set_message(self, value): + if not isinstance(value, str): + raise TypeError("message must be str") + + self.__message = value + + message = property(_get_message, _set_message) + + def _get_explanation(self): + return self.__explanation + + def _set_explanation(self, value): + if not isinstance(value, str): + raise TypeError("explanation must be str") + + self.__explanation = value + + explanation = property(_get_explanation, _set_explanation) + + def _get_defaultButton(self): + return self.__defaultButton + + def _set_defaultButton(self, value): + if not isinstance(value, str): + raise TypeError("defaultButton must be str") + + self.__defaultButton = value + + defaultButton = property(_get_defaultButton, _set_defaultButton) + + def _get_okButtonString(self): + return self.__okButtonString + + def _set_okButtonString(self, value): + if not isinstance(value, str): + raise TypeError("okButtonString must be str") + + self.__okButtonString = value + + okButtonString = property(_get_okButtonString, _set_okButtonString) + + def _get_okButtonAction(self): + return self.__okButtonAction + + def _set_okButtonAction(self, value): + if not isinstance(value, StoreBuyproductResp._dialog._okButtonAction): + raise TypeError( + "okButtonAction must be StoreBuyproductResp._dialog._okButtonAction" + ) + + self.__okButtonAction = value + + okButtonAction = property(_get_okButtonAction, _set_okButtonAction) + + def _get_cancelButtonString(self): + return self.__cancelButtonString + + def _set_cancelButtonString(self, value): + if not isinstance(value, str): + raise TypeError("cancelButtonString must be str") + + self.__cancelButtonString = value + + cancelButtonString = property(_get_cancelButtonString, _set_cancelButtonString) + + def _get_initialCheckboxValue(self): + return self.__initialCheckboxValue + + def _set_initialCheckboxValue(self, value): + if not isinstance(value, bool): + raise TypeError("initialCheckboxValue must be bool") + + self.__initialCheckboxValue = value + + initialCheckboxValue = property( + _get_initialCheckboxValue, _set_initialCheckboxValue + ) + + @staticmethod + def from_dict(d): + v = {} + if "kind" in d: + v["kind"] = ( + str.from_dict(d["kind"]) if hasattr(str, "from_dict") else d["kind"] + ) + if "m-allowed" in d: + v["m_allowed"] = ( + bool.from_dict(d["m-allowed"]) + if hasattr(bool, "from_dict") + else d["m-allowed"] + ) + if "use-keychain" in d: + v["use_keychain"] = ( + bool.from_dict(d["use-keychain"]) + if hasattr(bool, "from_dict") + else d["use-keychain"] + ) + if "isFree" in d: + v["isFree"] = ( + bool.from_dict(d["isFree"]) + if hasattr(bool, "from_dict") + else d["isFree"] + ) + if "message" in d: + v["message"] = ( + str.from_dict(d["message"]) + if hasattr(str, "from_dict") + else d["message"] + ) + if "explanation" in d: + v["explanation"] = ( + str.from_dict(d["explanation"]) + if hasattr(str, "from_dict") + else d["explanation"] + ) + if "defaultButton" in d: + v["defaultButton"] = ( + str.from_dict(d["defaultButton"]) + if hasattr(str, "from_dict") + else d["defaultButton"] + ) + if "okButtonString" in d: + v["okButtonString"] = ( + str.from_dict(d["okButtonString"]) + if hasattr(str, "from_dict") + else d["okButtonString"] + ) + if "okButtonAction" in d: + v["okButtonAction"] = ( + StoreBuyproductResp._dialog._okButtonAction.from_dict( + d["okButtonAction"] + ) + if hasattr(StoreBuyproductResp._dialog._okButtonAction, "from_dict") + else d["okButtonAction"] + ) + if "cancelButtonString" in d: + v["cancelButtonString"] = ( + str.from_dict(d["cancelButtonString"]) + if hasattr(str, "from_dict") + else d["cancelButtonString"] + ) + if "initialCheckboxValue" in d: + v["initialCheckboxValue"] = ( + bool.from_dict(d["initialCheckboxValue"]) + if hasattr(bool, "from_dict") + else d["initialCheckboxValue"] + ) + return StoreBuyproductResp._dialog(**v) + + def as_dict(self): + d = {} + if self.__kind is not None: + d["kind"] = ( + self.__kind.as_dict() + if hasattr(self.__kind, "as_dict") + else self.__kind + ) + if self.__m_allowed is not None: + d["m-allowed"] = ( + self.__m_allowed.as_dict() + if hasattr(self.__m_allowed, "as_dict") + else self.__m_allowed + ) + if self.__use_keychain is not None: + d["use-keychain"] = ( + self.__use_keychain.as_dict() + if hasattr(self.__use_keychain, "as_dict") + else self.__use_keychain + ) + if self.__isFree is not None: + d["isFree"] = ( + self.__isFree.as_dict() + if hasattr(self.__isFree, "as_dict") + else self.__isFree + ) + if self.__message is not None: + d["message"] = ( + self.__message.as_dict() + if hasattr(self.__message, "as_dict") + else self.__message + ) + if self.__explanation is not None: + d["explanation"] = ( + self.__explanation.as_dict() + if hasattr(self.__explanation, "as_dict") + else self.__explanation + ) + if self.__defaultButton is not None: + d["defaultButton"] = ( + self.__defaultButton.as_dict() + if hasattr(self.__defaultButton, "as_dict") + else self.__defaultButton + ) + if self.__okButtonString is not None: + d["okButtonString"] = ( + self.__okButtonString.as_dict() + if hasattr(self.__okButtonString, "as_dict") + else self.__okButtonString + ) + if self.__okButtonAction is not None: + d["okButtonAction"] = ( + self.__okButtonAction.as_dict() + if hasattr(self.__okButtonAction, "as_dict") + else self.__okButtonAction + ) + if self.__cancelButtonString is not None: + d["cancelButtonString"] = ( + self.__cancelButtonString.as_dict() + if hasattr(self.__cancelButtonString, "as_dict") + else self.__cancelButtonString + ) + if self.__initialCheckboxValue is not None: + d["initialCheckboxValue"] = ( + self.__initialCheckboxValue.as_dict() + if hasattr(self.__initialCheckboxValue, "as_dict") + else self.__initialCheckboxValue + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__kind[:20] if isinstance(self.__kind, bytes) else self.__kind + ), + limitedRepr( + self.__m_allowed[:20] + if isinstance(self.__m_allowed, bytes) + else self.__m_allowed + ), + limitedRepr( + self.__use_keychain[:20] + if isinstance(self.__use_keychain, bytes) + else self.__use_keychain + ), + limitedRepr( + self.__isFree[:20] + if isinstance(self.__isFree, bytes) + else self.__isFree + ), + limitedRepr( + self.__message[:20] + if isinstance(self.__message, bytes) + else self.__message + ), + limitedRepr( + self.__explanation[:20] + if isinstance(self.__explanation, bytes) + else self.__explanation + ), + limitedRepr( + self.__defaultButton[:20] + if isinstance(self.__defaultButton, bytes) + else self.__defaultButton + ), + limitedRepr( + self.__okButtonString[:20] + if isinstance(self.__okButtonString, bytes) + else self.__okButtonString + ), + limitedRepr( + self.__okButtonAction[:20] + if isinstance(self.__okButtonAction, bytes) + else self.__okButtonAction + ), + limitedRepr( + self.__cancelButtonString[:20] + if isinstance(self.__cancelButtonString, bytes) + else self.__cancelButtonString + ), + limitedRepr( + self.__initialCheckboxValue[:20] + if isinstance(self.__initialCheckboxValue, bytes) + else self.__initialCheckboxValue + ), + ) + + class _songList: + class _metadata: + class _MacUIRequiredDeviceCapabilities: + + _types_map = { + "arm64": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "arm64": { + "required": True, + }, + } + + def __init__(self, arm64: bool = None): + pass + self.__arm64 = arm64 + + def _get_arm64(self): + return self.__arm64 + + def _set_arm64(self, value): + if not isinstance(value, bool): + raise TypeError("arm64 must be bool") + + self.__arm64 = value + + arm64 = property(_get_arm64, _set_arm64) + + @staticmethod + def from_dict(d): + v = {} + if "arm64" in d: + v["arm64"] = ( + bool.from_dict(d["arm64"]) + if hasattr(bool, "from_dict") + else d["arm64"] + ) + return StoreBuyproductResp._songList._metadata._MacUIRequiredDeviceCapabilities( + **v + ) + + def as_dict(self): + d = {} + if self.__arm64 is not None: + d["arm64"] = ( + self.__arm64.as_dict() + if hasattr(self.__arm64, "as_dict") + else self.__arm64 + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__arm64[:20] + if isinstance(self.__arm64, bytes) + else self.__arm64 + ) + ) + + class _UIRequiredDeviceCapabilities: + + _types_map = { + "arm64": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "arm64": { + "required": True, + }, + } + + def __init__(self, arm64: bool = None): + pass + self.__arm64 = arm64 + + def _get_arm64(self): + return self.__arm64 + + def _set_arm64(self, value): + if not isinstance(value, bool): + raise TypeError("arm64 must be bool") + + self.__arm64 = value + + arm64 = property(_get_arm64, _set_arm64) + + @staticmethod + def from_dict(d): + v = {} + if "arm64" in d: + v["arm64"] = ( + bool.from_dict(d["arm64"]) + if hasattr(bool, "from_dict") + else d["arm64"] + ) + return StoreBuyproductResp._songList._metadata._UIRequiredDeviceCapabilities( + **v + ) + + def as_dict(self): + d = {} + if self.__arm64 is not None: + d["arm64"] = ( + self.__arm64.as_dict() + if hasattr(self.__arm64, "as_dict") + else self.__arm64 + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__arm64[:20] + if isinstance(self.__arm64, bytes) + else self.__arm64 + ) + ) + + class _rating: + + _types_map = { + "content": {"type": str, "subtype": None}, + "label": {"type": str, "subtype": None}, + "rank": {"type": int, "subtype": None}, + "system": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "content": { + "required": True, + }, + "label": { + "required": True, + }, + "rank": { + "required": True, + }, + "system": { + "required": True, + }, + } + + def __init__( + self, + content: str = None, + label: str = None, + rank: int = None, + system: str = None, + ): + pass + self.__content = content + self.__label = label + self.__rank = rank + self.__system = system + + def _get_content(self): + return self.__content + + def _set_content(self, value): + if not isinstance(value, str): + raise TypeError("content must be str") + + self.__content = value + + content = property(_get_content, _set_content) + + def _get_label(self): + return self.__label + + def _set_label(self, value): + if not isinstance(value, str): + raise TypeError("label must be str") + + self.__label = value + + label = property(_get_label, _set_label) + + def _get_rank(self): + return self.__rank + + def _set_rank(self, value): + if not isinstance(value, int): + raise TypeError("rank must be int") + + self.__rank = value + + rank = property(_get_rank, _set_rank) + + def _get_system(self): + return self.__system + + def _set_system(self, value): + if not isinstance(value, str): + raise TypeError("system must be str") + + self.__system = value + + system = property(_get_system, _set_system) + + @staticmethod + def from_dict(d): + v = {} + if "content" in d: + v["content"] = ( + str.from_dict(d["content"]) + if hasattr(str, "from_dict") + else d["content"] + ) + if "label" in d: + v["label"] = ( + str.from_dict(d["label"]) + if hasattr(str, "from_dict") + else d["label"] + ) + if "rank" in d: + v["rank"] = ( + int.from_dict(d["rank"]) + if hasattr(int, "from_dict") + else d["rank"] + ) + if "system" in d: + v["system"] = ( + str.from_dict(d["system"]) + if hasattr(str, "from_dict") + else d["system"] + ) + return StoreBuyproductResp._songList._metadata._rating(**v) + + def as_dict(self): + d = {} + if self.__content is not None: + d["content"] = ( + self.__content.as_dict() + if hasattr(self.__content, "as_dict") + else self.__content + ) + if self.__label is not None: + d["label"] = ( + self.__label.as_dict() + if hasattr(self.__label, "as_dict") + else self.__label + ) + if self.__rank is not None: + d["rank"] = ( + self.__rank.as_dict() + if hasattr(self.__rank, "as_dict") + else self.__rank + ) + if self.__system is not None: + d["system"] = ( + self.__system.as_dict() + if hasattr(self.__system, "as_dict") + else self.__system + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__content[:20] + if isinstance(self.__content, bytes) + else self.__content + ), + limitedRepr( + self.__label[:20] + if isinstance(self.__label, bytes) + else self.__label + ), + limitedRepr( + self.__rank[:20] + if isinstance(self.__rank, bytes) + else self.__rank + ), + limitedRepr( + self.__system[:20] + if isinstance(self.__system, bytes) + else self.__system + ), + ) + + class _nameTranscriptions: + + _types_map = { + "zh_Hans_CN": {"type": list, "subtype": str}, + } + _formats_map = {} + _validations_map = { + "zh_Hans_CN": { + "required": True, + }, + } + + def __init__(self, zh_Hans_CN: List[str] = None): + pass + self.__zh_Hans_CN = zh_Hans_CN + + def _get_zh_Hans_CN(self): + return self.__zh_Hans_CN + + def _set_zh_Hans_CN(self, value): + if not isinstance(value, list): + raise TypeError("zh_Hans_CN must be list") + if not all(isinstance(i, str) for i in value): + raise TypeError("zh_Hans_CN list values must be str") + + self.__zh_Hans_CN = value + + zh_Hans_CN = property(_get_zh_Hans_CN, _set_zh_Hans_CN) + + @staticmethod + def from_dict(d): + v = {} + if "zh-Hans-CN" in d: + v["zh_Hans_CN"] = [ + str.from_dict(p) if hasattr(str, "from_dict") else p + for p in d["zh-Hans-CN"] + ] + return StoreBuyproductResp._songList._metadata._nameTranscriptions( + **v + ) + + def as_dict(self): + d = {} + if self.__zh_Hans_CN is not None: + d["zh-Hans-CN"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__zh_Hans_CN + ] + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__zh_Hans_CN[:20] + if isinstance(self.__zh_Hans_CN, bytes) + else self.__zh_Hans_CN + ) + ) + + _types_map = { + "MacUIRequiredDeviceCapabilities": { + "type": _MacUIRequiredDeviceCapabilities, + "subtype": None, + }, + "UIRequiredDeviceCapabilities": { + "type": _UIRequiredDeviceCapabilities, + "subtype": None, + }, + "WKRunsIndependentlyOfCompanionApp": {"type": bool, "subtype": None}, + "WKWatchOnly": {"type": bool, "subtype": None}, + "appleWatchEnabled": {"type": bool, "subtype": None}, + "artistId": {"type": int, "subtype": None}, + "artistName": {"type": str, "subtype": None}, + "bundleDisplayName": {"type": str, "subtype": None}, + "bundleShortVersionString": {"type": str, "subtype": None}, + "bundleVersion": {"type": str, "subtype": None}, + "copyright": {"type": str, "subtype": None}, + "fileExtension": {"type": str, "subtype": None}, + "gameCenterEnabled": {"type": bool, "subtype": None}, + "gameCenterEverEnabled": {"type": bool, "subtype": None}, + "genre": {"type": str, "subtype": None}, + "genreId": {"type": int, "subtype": None}, + "itemId": {"type": int, "subtype": None}, + "itemName": {"type": str, "subtype": None}, + "kind": {"type": str, "subtype": None}, + "nameTranscriptions": {"type": _nameTranscriptions, "subtype": None}, + "playlistName": {"type": str, "subtype": None}, + "product_type": {"type": str, "subtype": None}, + "rating": {"type": _rating, "subtype": None}, + "releaseDate": {"type": str, "subtype": None}, + "requiresRosetta": {"type": bool, "subtype": None}, + "runsOnAppleSilicon": {"type": bool, "subtype": None}, + "runsOnIntel": {"type": bool, "subtype": None}, + "s": {"type": int, "subtype": None}, + "software_platform": {"type": str, "subtype": None}, + "softwareIcon57x57URL": {"type": str, "subtype": None}, + "softwareIconNeedsShine": {"type": bool, "subtype": None}, + "softwareSupportedDeviceIds": {"type": list, "subtype": int}, + "softwareVersionBundleId": {"type": str, "subtype": None}, + "softwareVersionExternalIdentifier": {"type": int, "subtype": None}, + "softwareVersionExternalIdentifiers": {"type": list, "subtype": int}, + "vendorId": {"type": int, "subtype": None}, + "drmVersionNumber": {"type": int, "subtype": None}, + "versionRestrictions": {"type": int, "subtype": None}, + "storeCohort": {"type": str, "subtype": None}, + "hasOrEverHasHadIAP": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "MacUIRequiredDeviceCapabilities": { + "required": True, + }, + "UIRequiredDeviceCapabilities": { + "required": True, + }, + "WKRunsIndependentlyOfCompanionApp": { + "required": True, + }, + "WKWatchOnly": { + "required": True, + }, + "appleWatchEnabled": { + "required": True, + }, + "artistId": { + "required": True, + }, + "artistName": { + "required": True, + }, + "bundleDisplayName": { + "required": True, + }, + "bundleShortVersionString": { + "required": True, + }, + "bundleVersion": { + "required": True, + }, + "copyright": { + "required": True, + }, + "fileExtension": { + "required": True, + }, + "gameCenterEnabled": { + "required": True, + }, + "gameCenterEverEnabled": { + "required": True, + }, + "genre": { + "required": True, + }, + "genreId": { + "required": True, + }, + "itemId": { + "required": True, + }, + "itemName": { + "required": True, + }, + "kind": { + "required": True, + }, + "nameTranscriptions": { + "required": True, + }, + "playlistName": { + "required": True, + }, + "product_type": { + "required": True, + }, + "rating": { + "required": True, + }, + "releaseDate": { + "required": True, + }, + "requiresRosetta": { + "required": True, + }, + "runsOnAppleSilicon": { + "required": True, + }, + "runsOnIntel": { + "required": True, + }, + "s": { + "required": True, + }, + "software_platform": { + "required": True, + }, + "softwareIcon57x57URL": { + "required": True, + }, + "softwareIconNeedsShine": { + "required": True, + }, + "softwareSupportedDeviceIds": { + "required": True, + }, + "softwareVersionBundleId": { + "required": True, + }, + "softwareVersionExternalIdentifier": { + "required": True, + }, + "softwareVersionExternalIdentifiers": { + "required": True, + }, + "vendorId": { + "required": True, + }, + "drmVersionNumber": { + "required": True, + }, + "versionRestrictions": { + "required": True, + }, + "storeCohort": { + "required": True, + }, + "hasOrEverHasHadIAP": { + "required": True, + }, + } + + def __init__( + self, + MacUIRequiredDeviceCapabilities: _MacUIRequiredDeviceCapabilities = None, + UIRequiredDeviceCapabilities: _UIRequiredDeviceCapabilities = None, + WKRunsIndependentlyOfCompanionApp: bool = None, + WKWatchOnly: bool = None, + appleWatchEnabled: bool = None, + artistId: int = None, + artistName: str = None, + bundleDisplayName: str = None, + bundleShortVersionString: str = None, + bundleVersion: str = None, + copyright: str = None, + fileExtension: str = None, + gameCenterEnabled: bool = None, + gameCenterEverEnabled: bool = None, + genre: str = None, + genreId: int = None, + itemId: int = None, + itemName: str = None, + kind: str = None, + nameTranscriptions: _nameTranscriptions = None, + playlistName: str = None, + product_type: str = None, + rating: _rating = None, + releaseDate: str = None, + requiresRosetta: bool = None, + runsOnAppleSilicon: bool = None, + runsOnIntel: bool = None, + s: int = None, + software_platform: str = None, + softwareIcon57x57URL: str = None, + softwareIconNeedsShine: bool = None, + softwareSupportedDeviceIds: List[int] = None, + softwareVersionBundleId: str = None, + softwareVersionExternalIdentifier: int = None, + softwareVersionExternalIdentifiers: List[int] = None, + vendorId: int = None, + drmVersionNumber: int = None, + versionRestrictions: int = None, + storeCohort: str = None, + hasOrEverHasHadIAP: bool = None, + ): + pass + self.__MacUIRequiredDeviceCapabilities = MacUIRequiredDeviceCapabilities + self.__UIRequiredDeviceCapabilities = UIRequiredDeviceCapabilities + self.__WKRunsIndependentlyOfCompanionApp = ( + WKRunsIndependentlyOfCompanionApp + ) + self.__WKWatchOnly = WKWatchOnly + self.__appleWatchEnabled = appleWatchEnabled + self.__artistId = artistId + self.__artistName = artistName + self.__bundleDisplayName = bundleDisplayName + self.__bundleShortVersionString = bundleShortVersionString + self.__bundleVersion = bundleVersion + self.__copyright = copyright + self.__fileExtension = fileExtension + self.__gameCenterEnabled = gameCenterEnabled + self.__gameCenterEverEnabled = gameCenterEverEnabled + self.__genre = genre + self.__genreId = genreId + self.__itemId = itemId + self.__itemName = itemName + self.__kind = kind + self.__nameTranscriptions = nameTranscriptions + self.__playlistName = playlistName + self.__product_type = product_type + self.__rating = rating + self.__releaseDate = releaseDate + self.__requiresRosetta = requiresRosetta + self.__runsOnAppleSilicon = runsOnAppleSilicon + self.__runsOnIntel = runsOnIntel + self.__s = s + self.__software_platform = software_platform + self.__softwareIcon57x57URL = softwareIcon57x57URL + self.__softwareIconNeedsShine = softwareIconNeedsShine + self.__softwareSupportedDeviceIds = softwareSupportedDeviceIds + self.__softwareVersionBundleId = softwareVersionBundleId + self.__softwareVersionExternalIdentifier = ( + softwareVersionExternalIdentifier + ) + self.__softwareVersionExternalIdentifiers = ( + softwareVersionExternalIdentifiers + ) + self.__vendorId = vendorId + self.__drmVersionNumber = drmVersionNumber + self.__versionRestrictions = versionRestrictions + self.__storeCohort = storeCohort + self.__hasOrEverHasHadIAP = hasOrEverHasHadIAP + + def _get_MacUIRequiredDeviceCapabilities(self): + return self.__MacUIRequiredDeviceCapabilities + + def _set_MacUIRequiredDeviceCapabilities(self, value): + if not isinstance( + value, + StoreBuyproductResp._songList._metadata._MacUIRequiredDeviceCapabilities, + ): + raise TypeError( + "MacUIRequiredDeviceCapabilities must be StoreBuyproductResp._songList._metadata._MacUIRequiredDeviceCapabilities" + ) + + self.__MacUIRequiredDeviceCapabilities = value + + MacUIRequiredDeviceCapabilities = property( + _get_MacUIRequiredDeviceCapabilities, + _set_MacUIRequiredDeviceCapabilities, + ) + + def _get_UIRequiredDeviceCapabilities(self): + return self.__UIRequiredDeviceCapabilities + + def _set_UIRequiredDeviceCapabilities(self, value): + if not isinstance( + value, + StoreBuyproductResp._songList._metadata._UIRequiredDeviceCapabilities, + ): + raise TypeError( + "UIRequiredDeviceCapabilities must be StoreBuyproductResp._songList._metadata._UIRequiredDeviceCapabilities" + ) + + self.__UIRequiredDeviceCapabilities = value + + UIRequiredDeviceCapabilities = property( + _get_UIRequiredDeviceCapabilities, _set_UIRequiredDeviceCapabilities + ) + + def _get_WKRunsIndependentlyOfCompanionApp(self): + return self.__WKRunsIndependentlyOfCompanionApp + + def _set_WKRunsIndependentlyOfCompanionApp(self, value): + if not isinstance(value, bool): + raise TypeError("WKRunsIndependentlyOfCompanionApp must be bool") + + self.__WKRunsIndependentlyOfCompanionApp = value + + WKRunsIndependentlyOfCompanionApp = property( + _get_WKRunsIndependentlyOfCompanionApp, + _set_WKRunsIndependentlyOfCompanionApp, + ) + + def _get_WKWatchOnly(self): + return self.__WKWatchOnly + + def _set_WKWatchOnly(self, value): + if not isinstance(value, bool): + raise TypeError("WKWatchOnly must be bool") + + self.__WKWatchOnly = value + + WKWatchOnly = property(_get_WKWatchOnly, _set_WKWatchOnly) + + def _get_appleWatchEnabled(self): + return self.__appleWatchEnabled + + def _set_appleWatchEnabled(self, value): + if not isinstance(value, bool): + raise TypeError("appleWatchEnabled must be bool") + + self.__appleWatchEnabled = value + + appleWatchEnabled = property(_get_appleWatchEnabled, _set_appleWatchEnabled) + + def _get_artistId(self): + return self.__artistId + + def _set_artistId(self, value): + if not isinstance(value, int): + raise TypeError("artistId must be int") + + self.__artistId = value + + artistId = property(_get_artistId, _set_artistId) + + def _get_artistName(self): + return self.__artistName + + def _set_artistName(self, value): + if not isinstance(value, str): + raise TypeError("artistName must be str") + + self.__artistName = value + + artistName = property(_get_artistName, _set_artistName) + + def _get_bundleDisplayName(self): + return self.__bundleDisplayName + + def _set_bundleDisplayName(self, value): + if not isinstance(value, str): + raise TypeError("bundleDisplayName must be str") + + self.__bundleDisplayName = value + + bundleDisplayName = property(_get_bundleDisplayName, _set_bundleDisplayName) + + def _get_bundleShortVersionString(self): + return self.__bundleShortVersionString + + def _set_bundleShortVersionString(self, value): + if not isinstance(value, str): + raise TypeError("bundleShortVersionString must be str") + + self.__bundleShortVersionString = value + + bundleShortVersionString = property( + _get_bundleShortVersionString, _set_bundleShortVersionString + ) + + def _get_bundleVersion(self): + return self.__bundleVersion + + def _set_bundleVersion(self, value): + if not isinstance(value, str): + raise TypeError("bundleVersion must be str") + + self.__bundleVersion = value + + bundleVersion = property(_get_bundleVersion, _set_bundleVersion) + + def _get_copyright(self): + return self.__copyright + + def _set_copyright(self, value): + if not isinstance(value, str): + raise TypeError("copyright must be str") + + self.__copyright = value + + copyright = property(_get_copyright, _set_copyright) + + def _get_fileExtension(self): + return self.__fileExtension + + def _set_fileExtension(self, value): + if not isinstance(value, str): + raise TypeError("fileExtension must be str") + + self.__fileExtension = value + + fileExtension = property(_get_fileExtension, _set_fileExtension) + + def _get_gameCenterEnabled(self): + return self.__gameCenterEnabled + + def _set_gameCenterEnabled(self, value): + if not isinstance(value, bool): + raise TypeError("gameCenterEnabled must be bool") + + self.__gameCenterEnabled = value + + gameCenterEnabled = property(_get_gameCenterEnabled, _set_gameCenterEnabled) + + def _get_gameCenterEverEnabled(self): + return self.__gameCenterEverEnabled + + def _set_gameCenterEverEnabled(self, value): + if not isinstance(value, bool): + raise TypeError("gameCenterEverEnabled must be bool") + + self.__gameCenterEverEnabled = value + + gameCenterEverEnabled = property( + _get_gameCenterEverEnabled, _set_gameCenterEverEnabled + ) + + def _get_genre(self): + return self.__genre + + def _set_genre(self, value): + if not isinstance(value, str): + raise TypeError("genre must be str") + + self.__genre = value + + genre = property(_get_genre, _set_genre) + + def _get_genreId(self): + return self.__genreId + + def _set_genreId(self, value): + if not isinstance(value, int): + raise TypeError("genreId must be int") + + self.__genreId = value + + genreId = property(_get_genreId, _set_genreId) + + def _get_itemId(self): + return self.__itemId + + def _set_itemId(self, value): + if not isinstance(value, int): + raise TypeError("itemId must be int") + + self.__itemId = value + + itemId = property(_get_itemId, _set_itemId) + + def _get_itemName(self): + return self.__itemName + + def _set_itemName(self, value): + if not isinstance(value, str): + raise TypeError("itemName must be str") + + self.__itemName = value + + itemName = property(_get_itemName, _set_itemName) + + def _get_kind(self): + return self.__kind + + def _set_kind(self, value): + if not isinstance(value, str): + raise TypeError("kind must be str") + + self.__kind = value + + kind = property(_get_kind, _set_kind) + + def _get_nameTranscriptions(self): + return self.__nameTranscriptions + + def _set_nameTranscriptions(self, value): + if not isinstance( + value, StoreBuyproductResp._songList._metadata._nameTranscriptions + ): + raise TypeError( + "nameTranscriptions must be StoreBuyproductResp._songList._metadata._nameTranscriptions" + ) + + self.__nameTranscriptions = value + + nameTranscriptions = property( + _get_nameTranscriptions, _set_nameTranscriptions + ) + + def _get_playlistName(self): + return self.__playlistName + + def _set_playlistName(self, value): + if not isinstance(value, str): + raise TypeError("playlistName must be str") + + self.__playlistName = value + + playlistName = property(_get_playlistName, _set_playlistName) + + def _get_product_type(self): + return self.__product_type + + def _set_product_type(self, value): + if not isinstance(value, str): + raise TypeError("product_type must be str") + + self.__product_type = value + + product_type = property(_get_product_type, _set_product_type) + + def _get_rating(self): + return self.__rating + + def _set_rating(self, value): + if not isinstance( + value, StoreBuyproductResp._songList._metadata._rating + ): + raise TypeError( + "rating must be StoreBuyproductResp._songList._metadata._rating" + ) + + self.__rating = value + + rating = property(_get_rating, _set_rating) + + def _get_releaseDate(self): + return self.__releaseDate + + def _set_releaseDate(self, value): + if not isinstance(value, str): + raise TypeError("releaseDate must be str") + + self.__releaseDate = value + + releaseDate = property(_get_releaseDate, _set_releaseDate) + + def _get_requiresRosetta(self): + return self.__requiresRosetta + + def _set_requiresRosetta(self, value): + if not isinstance(value, bool): + raise TypeError("requiresRosetta must be bool") + + self.__requiresRosetta = value + + requiresRosetta = property(_get_requiresRosetta, _set_requiresRosetta) + + def _get_runsOnAppleSilicon(self): + return self.__runsOnAppleSilicon + + def _set_runsOnAppleSilicon(self, value): + if not isinstance(value, bool): + raise TypeError("runsOnAppleSilicon must be bool") + + self.__runsOnAppleSilicon = value + + runsOnAppleSilicon = property( + _get_runsOnAppleSilicon, _set_runsOnAppleSilicon + ) + + def _get_runsOnIntel(self): + return self.__runsOnIntel + + def _set_runsOnIntel(self, value): + if not isinstance(value, bool): + raise TypeError("runsOnIntel must be bool") + + self.__runsOnIntel = value + + runsOnIntel = property(_get_runsOnIntel, _set_runsOnIntel) + + def _get_s(self): + return self.__s + + def _set_s(self, value): + if not isinstance(value, int): + raise TypeError("s must be int") + + self.__s = value + + s = property(_get_s, _set_s) + + def _get_software_platform(self): + return self.__software_platform + + def _set_software_platform(self, value): + if not isinstance(value, str): + raise TypeError("software_platform must be str") + + self.__software_platform = value + + software_platform = property(_get_software_platform, _set_software_platform) + + def _get_softwareIcon57x57URL(self): + return self.__softwareIcon57x57URL + + def _set_softwareIcon57x57URL(self, value): + if not isinstance(value, str): + raise TypeError("softwareIcon57x57URL must be str") + + self.__softwareIcon57x57URL = value + + softwareIcon57x57URL = property( + _get_softwareIcon57x57URL, _set_softwareIcon57x57URL + ) + + def _get_softwareIconNeedsShine(self): + return self.__softwareIconNeedsShine + + def _set_softwareIconNeedsShine(self, value): + if not isinstance(value, bool): + raise TypeError("softwareIconNeedsShine must be bool") + + self.__softwareIconNeedsShine = value + + softwareIconNeedsShine = property( + _get_softwareIconNeedsShine, _set_softwareIconNeedsShine + ) + + def _get_softwareSupportedDeviceIds(self): + return self.__softwareSupportedDeviceIds + + def _set_softwareSupportedDeviceIds(self, value): + if not isinstance(value, list): + raise TypeError("softwareSupportedDeviceIds must be list") + if not all(isinstance(i, int) for i in value): + raise TypeError( + "softwareSupportedDeviceIds list values must be int" + ) + + self.__softwareSupportedDeviceIds = value + + softwareSupportedDeviceIds = property( + _get_softwareSupportedDeviceIds, _set_softwareSupportedDeviceIds + ) + + def _get_softwareVersionBundleId(self): + return self.__softwareVersionBundleId + + def _set_softwareVersionBundleId(self, value): + if not isinstance(value, str): + raise TypeError("softwareVersionBundleId must be str") + + self.__softwareVersionBundleId = value + + softwareVersionBundleId = property( + _get_softwareVersionBundleId, _set_softwareVersionBundleId + ) + + def _get_softwareVersionExternalIdentifier(self): + return self.__softwareVersionExternalIdentifier + + def _set_softwareVersionExternalIdentifier(self, value): + if not isinstance(value, int): + raise TypeError("softwareVersionExternalIdentifier must be int") + + self.__softwareVersionExternalIdentifier = value + + softwareVersionExternalIdentifier = property( + _get_softwareVersionExternalIdentifier, + _set_softwareVersionExternalIdentifier, + ) + + def _get_softwareVersionExternalIdentifiers(self): + return self.__softwareVersionExternalIdentifiers + + def _set_softwareVersionExternalIdentifiers(self, value): + if not isinstance(value, list): + raise TypeError("softwareVersionExternalIdentifiers must be list") + if not all(isinstance(i, int) for i in value): + raise TypeError( + "softwareVersionExternalIdentifiers list values must be int" + ) + + self.__softwareVersionExternalIdentifiers = value + + softwareVersionExternalIdentifiers = property( + _get_softwareVersionExternalIdentifiers, + _set_softwareVersionExternalIdentifiers, + ) + + def _get_vendorId(self): + return self.__vendorId + + def _set_vendorId(self, value): + if not isinstance(value, int): + raise TypeError("vendorId must be int") + + self.__vendorId = value + + vendorId = property(_get_vendorId, _set_vendorId) + + def _get_drmVersionNumber(self): + return self.__drmVersionNumber + + def _set_drmVersionNumber(self, value): + if not isinstance(value, int): + raise TypeError("drmVersionNumber must be int") + + self.__drmVersionNumber = value + + drmVersionNumber = property(_get_drmVersionNumber, _set_drmVersionNumber) + + def _get_versionRestrictions(self): + return self.__versionRestrictions + + def _set_versionRestrictions(self, value): + if not isinstance(value, int): + raise TypeError("versionRestrictions must be int") + + self.__versionRestrictions = value + + versionRestrictions = property( + _get_versionRestrictions, _set_versionRestrictions + ) + + def _get_storeCohort(self): + return self.__storeCohort + + def _set_storeCohort(self, value): + if not isinstance(value, str): + raise TypeError("storeCohort must be str") + + self.__storeCohort = value + + storeCohort = property(_get_storeCohort, _set_storeCohort) + + def _get_hasOrEverHasHadIAP(self): + return self.__hasOrEverHasHadIAP + + def _set_hasOrEverHasHadIAP(self, value): + if not isinstance(value, bool): + raise TypeError("hasOrEverHasHadIAP must be bool") + + self.__hasOrEverHasHadIAP = value + + hasOrEverHasHadIAP = property( + _get_hasOrEverHasHadIAP, _set_hasOrEverHasHadIAP + ) + + @staticmethod + def from_dict(d): + v = {} + if "MacUIRequiredDeviceCapabilities" in d: + v["MacUIRequiredDeviceCapabilities"] = ( + StoreBuyproductResp._songList._metadata._MacUIRequiredDeviceCapabilities.from_dict( + d["MacUIRequiredDeviceCapabilities"] + ) + if hasattr( + StoreBuyproductResp._songList._metadata._MacUIRequiredDeviceCapabilities, + "from_dict", + ) + else d["MacUIRequiredDeviceCapabilities"] + ) + if "UIRequiredDeviceCapabilities" in d: + v["UIRequiredDeviceCapabilities"] = ( + StoreBuyproductResp._songList._metadata._UIRequiredDeviceCapabilities.from_dict( + d["UIRequiredDeviceCapabilities"] + ) + if hasattr( + StoreBuyproductResp._songList._metadata._UIRequiredDeviceCapabilities, + "from_dict", + ) + else d["UIRequiredDeviceCapabilities"] + ) + if "WKRunsIndependentlyOfCompanionApp" in d: + v["WKRunsIndependentlyOfCompanionApp"] = ( + bool.from_dict(d["WKRunsIndependentlyOfCompanionApp"]) + if hasattr(bool, "from_dict") + else d["WKRunsIndependentlyOfCompanionApp"] + ) + if "WKWatchOnly" in d: + v["WKWatchOnly"] = ( + bool.from_dict(d["WKWatchOnly"]) + if hasattr(bool, "from_dict") + else d["WKWatchOnly"] + ) + if "appleWatchEnabled" in d: + v["appleWatchEnabled"] = ( + bool.from_dict(d["appleWatchEnabled"]) + if hasattr(bool, "from_dict") + else d["appleWatchEnabled"] + ) + if "artistId" in d: + v["artistId"] = ( + int.from_dict(d["artistId"]) + if hasattr(int, "from_dict") + else d["artistId"] + ) + if "artistName" in d: + v["artistName"] = ( + str.from_dict(d["artistName"]) + if hasattr(str, "from_dict") + else d["artistName"] + ) + if "bundleDisplayName" in d: + v["bundleDisplayName"] = ( + str.from_dict(d["bundleDisplayName"]) + if hasattr(str, "from_dict") + else d["bundleDisplayName"] + ) + if "bundleShortVersionString" in d: + v["bundleShortVersionString"] = ( + str.from_dict(d["bundleShortVersionString"]) + if hasattr(str, "from_dict") + else d["bundleShortVersionString"] + ) + if "bundleVersion" in d: + v["bundleVersion"] = ( + str.from_dict(d["bundleVersion"]) + if hasattr(str, "from_dict") + else d["bundleVersion"] + ) + if "copyright" in d: + v["copyright"] = ( + str.from_dict(d["copyright"]) + if hasattr(str, "from_dict") + else d["copyright"] + ) + if "fileExtension" in d: + v["fileExtension"] = ( + str.from_dict(d["fileExtension"]) + if hasattr(str, "from_dict") + else d["fileExtension"] + ) + if "gameCenterEnabled" in d: + v["gameCenterEnabled"] = ( + bool.from_dict(d["gameCenterEnabled"]) + if hasattr(bool, "from_dict") + else d["gameCenterEnabled"] + ) + if "gameCenterEverEnabled" in d: + v["gameCenterEverEnabled"] = ( + bool.from_dict(d["gameCenterEverEnabled"]) + if hasattr(bool, "from_dict") + else d["gameCenterEverEnabled"] + ) + if "genre" in d: + v["genre"] = ( + str.from_dict(d["genre"]) + if hasattr(str, "from_dict") + else d["genre"] + ) + if "genreId" in d: + v["genreId"] = ( + int.from_dict(d["genreId"]) + if hasattr(int, "from_dict") + else d["genreId"] + ) + if "itemId" in d: + v["itemId"] = ( + int.from_dict(d["itemId"]) + if hasattr(int, "from_dict") + else d["itemId"] + ) + if "itemName" in d: + v["itemName"] = ( + str.from_dict(d["itemName"]) + if hasattr(str, "from_dict") + else d["itemName"] + ) + if "kind" in d: + v["kind"] = ( + str.from_dict(d["kind"]) + if hasattr(str, "from_dict") + else d["kind"] + ) + if "nameTranscriptions" in d: + v["nameTranscriptions"] = ( + StoreBuyproductResp._songList._metadata._nameTranscriptions.from_dict( + d["nameTranscriptions"] + ) + if hasattr( + StoreBuyproductResp._songList._metadata._nameTranscriptions, + "from_dict", + ) + else d["nameTranscriptions"] + ) + if "playlistName" in d: + v["playlistName"] = ( + str.from_dict(d["playlistName"]) + if hasattr(str, "from_dict") + else d["playlistName"] + ) + if "product-type" in d: + v["product_type"] = ( + str.from_dict(d["product-type"]) + if hasattr(str, "from_dict") + else d["product-type"] + ) + if "rating" in d: + v["rating"] = ( + StoreBuyproductResp._songList._metadata._rating.from_dict( + d["rating"] + ) + if hasattr( + StoreBuyproductResp._songList._metadata._rating, "from_dict" + ) + else d["rating"] + ) + if "releaseDate" in d: + v["releaseDate"] = ( + str.from_dict(d["releaseDate"]) + if hasattr(str, "from_dict") + else d["releaseDate"] + ) + if "requiresRosetta" in d: + v["requiresRosetta"] = ( + bool.from_dict(d["requiresRosetta"]) + if hasattr(bool, "from_dict") + else d["requiresRosetta"] + ) + if "runsOnAppleSilicon" in d: + v["runsOnAppleSilicon"] = ( + bool.from_dict(d["runsOnAppleSilicon"]) + if hasattr(bool, "from_dict") + else d["runsOnAppleSilicon"] + ) + if "runsOnIntel" in d: + v["runsOnIntel"] = ( + bool.from_dict(d["runsOnIntel"]) + if hasattr(bool, "from_dict") + else d["runsOnIntel"] + ) + if "s" in d: + v["s"] = ( + int.from_dict(d["s"]) if hasattr(int, "from_dict") else d["s"] + ) + if "software-platform" in d: + v["software_platform"] = ( + str.from_dict(d["software-platform"]) + if hasattr(str, "from_dict") + else d["software-platform"] + ) + if "softwareIcon57x57URL" in d: + v["softwareIcon57x57URL"] = ( + str.from_dict(d["softwareIcon57x57URL"]) + if hasattr(str, "from_dict") + else d["softwareIcon57x57URL"] + ) + if "softwareIconNeedsShine" in d: + v["softwareIconNeedsShine"] = ( + bool.from_dict(d["softwareIconNeedsShine"]) + if hasattr(bool, "from_dict") + else d["softwareIconNeedsShine"] + ) + if "softwareSupportedDeviceIds" in d: + v["softwareSupportedDeviceIds"] = [ + int.from_dict(p) if hasattr(int, "from_dict") else p + for p in d["softwareSupportedDeviceIds"] + ] + if "softwareVersionBundleId" in d: + v["softwareVersionBundleId"] = ( + str.from_dict(d["softwareVersionBundleId"]) + if hasattr(str, "from_dict") + else d["softwareVersionBundleId"] + ) + if "softwareVersionExternalIdentifier" in d: + v["softwareVersionExternalIdentifier"] = ( + int.from_dict(d["softwareVersionExternalIdentifier"]) + if hasattr(int, "from_dict") + else d["softwareVersionExternalIdentifier"] + ) + if "softwareVersionExternalIdentifiers" in d: + v["softwareVersionExternalIdentifiers"] = [ + int.from_dict(p) if hasattr(int, "from_dict") else p + for p in d["softwareVersionExternalIdentifiers"] + ] + if "vendorId" in d: + v["vendorId"] = ( + int.from_dict(d["vendorId"]) + if hasattr(int, "from_dict") + else d["vendorId"] + ) + if "drmVersionNumber" in d: + v["drmVersionNumber"] = ( + int.from_dict(d["drmVersionNumber"]) + if hasattr(int, "from_dict") + else d["drmVersionNumber"] + ) + if "versionRestrictions" in d: + v["versionRestrictions"] = ( + int.from_dict(d["versionRestrictions"]) + if hasattr(int, "from_dict") + else d["versionRestrictions"] + ) + if "storeCohort" in d: + v["storeCohort"] = ( + str.from_dict(d["storeCohort"]) + if hasattr(str, "from_dict") + else d["storeCohort"] + ) + if "hasOrEverHasHadIAP" in d: + v["hasOrEverHasHadIAP"] = ( + bool.from_dict(d["hasOrEverHasHadIAP"]) + if hasattr(bool, "from_dict") + else d["hasOrEverHasHadIAP"] + ) + return StoreBuyproductResp._songList._metadata(**v) + + def as_dict(self): + d = {} + if self.__MacUIRequiredDeviceCapabilities is not None: + d["MacUIRequiredDeviceCapabilities"] = ( + self.__MacUIRequiredDeviceCapabilities.as_dict() + if hasattr(self.__MacUIRequiredDeviceCapabilities, "as_dict") + else self.__MacUIRequiredDeviceCapabilities + ) + if self.__UIRequiredDeviceCapabilities is not None: + d["UIRequiredDeviceCapabilities"] = ( + self.__UIRequiredDeviceCapabilities.as_dict() + if hasattr(self.__UIRequiredDeviceCapabilities, "as_dict") + else self.__UIRequiredDeviceCapabilities + ) + if self.__WKRunsIndependentlyOfCompanionApp is not None: + d["WKRunsIndependentlyOfCompanionApp"] = ( + self.__WKRunsIndependentlyOfCompanionApp.as_dict() + if hasattr(self.__WKRunsIndependentlyOfCompanionApp, "as_dict") + else self.__WKRunsIndependentlyOfCompanionApp + ) + if self.__WKWatchOnly is not None: + d["WKWatchOnly"] = ( + self.__WKWatchOnly.as_dict() + if hasattr(self.__WKWatchOnly, "as_dict") + else self.__WKWatchOnly + ) + if self.__appleWatchEnabled is not None: + d["appleWatchEnabled"] = ( + self.__appleWatchEnabled.as_dict() + if hasattr(self.__appleWatchEnabled, "as_dict") + else self.__appleWatchEnabled + ) + if self.__artistId is not None: + d["artistId"] = ( + self.__artistId.as_dict() + if hasattr(self.__artistId, "as_dict") + else self.__artistId + ) + if self.__artistName is not None: + d["artistName"] = ( + self.__artistName.as_dict() + if hasattr(self.__artistName, "as_dict") + else self.__artistName + ) + if self.__bundleDisplayName is not None: + d["bundleDisplayName"] = ( + self.__bundleDisplayName.as_dict() + if hasattr(self.__bundleDisplayName, "as_dict") + else self.__bundleDisplayName + ) + if self.__bundleShortVersionString is not None: + d["bundleShortVersionString"] = ( + self.__bundleShortVersionString.as_dict() + if hasattr(self.__bundleShortVersionString, "as_dict") + else self.__bundleShortVersionString + ) + if self.__bundleVersion is not None: + d["bundleVersion"] = ( + self.__bundleVersion.as_dict() + if hasattr(self.__bundleVersion, "as_dict") + else self.__bundleVersion + ) + if self.__copyright is not None: + d["copyright"] = ( + self.__copyright.as_dict() + if hasattr(self.__copyright, "as_dict") + else self.__copyright + ) + if self.__fileExtension is not None: + d["fileExtension"] = ( + self.__fileExtension.as_dict() + if hasattr(self.__fileExtension, "as_dict") + else self.__fileExtension + ) + if self.__gameCenterEnabled is not None: + d["gameCenterEnabled"] = ( + self.__gameCenterEnabled.as_dict() + if hasattr(self.__gameCenterEnabled, "as_dict") + else self.__gameCenterEnabled + ) + if self.__gameCenterEverEnabled is not None: + d["gameCenterEverEnabled"] = ( + self.__gameCenterEverEnabled.as_dict() + if hasattr(self.__gameCenterEverEnabled, "as_dict") + else self.__gameCenterEverEnabled + ) + if self.__genre is not None: + d["genre"] = ( + self.__genre.as_dict() + if hasattr(self.__genre, "as_dict") + else self.__genre + ) + if self.__genreId is not None: + d["genreId"] = ( + self.__genreId.as_dict() + if hasattr(self.__genreId, "as_dict") + else self.__genreId + ) + if self.__itemId is not None: + d["itemId"] = ( + self.__itemId.as_dict() + if hasattr(self.__itemId, "as_dict") + else self.__itemId + ) + if self.__itemName is not None: + d["itemName"] = ( + self.__itemName.as_dict() + if hasattr(self.__itemName, "as_dict") + else self.__itemName + ) + if self.__kind is not None: + d["kind"] = ( + self.__kind.as_dict() + if hasattr(self.__kind, "as_dict") + else self.__kind + ) + if self.__nameTranscriptions is not None: + d["nameTranscriptions"] = ( + self.__nameTranscriptions.as_dict() + if hasattr(self.__nameTranscriptions, "as_dict") + else self.__nameTranscriptions + ) + if self.__playlistName is not None: + d["playlistName"] = ( + self.__playlistName.as_dict() + if hasattr(self.__playlistName, "as_dict") + else self.__playlistName + ) + if self.__product_type is not None: + d["product-type"] = ( + self.__product_type.as_dict() + if hasattr(self.__product_type, "as_dict") + else self.__product_type + ) + if self.__rating is not None: + d["rating"] = ( + self.__rating.as_dict() + if hasattr(self.__rating, "as_dict") + else self.__rating + ) + if self.__releaseDate is not None: + d["releaseDate"] = ( + self.__releaseDate.as_dict() + if hasattr(self.__releaseDate, "as_dict") + else self.__releaseDate + ) + if self.__requiresRosetta is not None: + d["requiresRosetta"] = ( + self.__requiresRosetta.as_dict() + if hasattr(self.__requiresRosetta, "as_dict") + else self.__requiresRosetta + ) + if self.__runsOnAppleSilicon is not None: + d["runsOnAppleSilicon"] = ( + self.__runsOnAppleSilicon.as_dict() + if hasattr(self.__runsOnAppleSilicon, "as_dict") + else self.__runsOnAppleSilicon + ) + if self.__runsOnIntel is not None: + d["runsOnIntel"] = ( + self.__runsOnIntel.as_dict() + if hasattr(self.__runsOnIntel, "as_dict") + else self.__runsOnIntel + ) + if self.__s is not None: + d["s"] = ( + self.__s.as_dict() if hasattr(self.__s, "as_dict") else self.__s + ) + if self.__software_platform is not None: + d["software-platform"] = ( + self.__software_platform.as_dict() + if hasattr(self.__software_platform, "as_dict") + else self.__software_platform + ) + if self.__softwareIcon57x57URL is not None: + d["softwareIcon57x57URL"] = ( + self.__softwareIcon57x57URL.as_dict() + if hasattr(self.__softwareIcon57x57URL, "as_dict") + else self.__softwareIcon57x57URL + ) + if self.__softwareIconNeedsShine is not None: + d["softwareIconNeedsShine"] = ( + self.__softwareIconNeedsShine.as_dict() + if hasattr(self.__softwareIconNeedsShine, "as_dict") + else self.__softwareIconNeedsShine + ) + if self.__softwareSupportedDeviceIds is not None: + d["softwareSupportedDeviceIds"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__softwareSupportedDeviceIds + ] + if self.__softwareVersionBundleId is not None: + d["softwareVersionBundleId"] = ( + self.__softwareVersionBundleId.as_dict() + if hasattr(self.__softwareVersionBundleId, "as_dict") + else self.__softwareVersionBundleId + ) + if self.__softwareVersionExternalIdentifier is not None: + d["softwareVersionExternalIdentifier"] = ( + self.__softwareVersionExternalIdentifier.as_dict() + if hasattr(self.__softwareVersionExternalIdentifier, "as_dict") + else self.__softwareVersionExternalIdentifier + ) + if self.__softwareVersionExternalIdentifiers is not None: + d["softwareVersionExternalIdentifiers"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__softwareVersionExternalIdentifiers + ] + if self.__vendorId is not None: + d["vendorId"] = ( + self.__vendorId.as_dict() + if hasattr(self.__vendorId, "as_dict") + else self.__vendorId + ) + if self.__drmVersionNumber is not None: + d["drmVersionNumber"] = ( + self.__drmVersionNumber.as_dict() + if hasattr(self.__drmVersionNumber, "as_dict") + else self.__drmVersionNumber + ) + if self.__versionRestrictions is not None: + d["versionRestrictions"] = ( + self.__versionRestrictions.as_dict() + if hasattr(self.__versionRestrictions, "as_dict") + else self.__versionRestrictions + ) + if self.__storeCohort is not None: + d["storeCohort"] = ( + self.__storeCohort.as_dict() + if hasattr(self.__storeCohort, "as_dict") + else self.__storeCohort + ) + if self.__hasOrEverHasHadIAP is not None: + d["hasOrEverHasHadIAP"] = ( + self.__hasOrEverHasHadIAP.as_dict() + if hasattr(self.__hasOrEverHasHadIAP, "as_dict") + else self.__hasOrEverHasHadIAP + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__MacUIRequiredDeviceCapabilities[:20] + if isinstance(self.__MacUIRequiredDeviceCapabilities, bytes) + else self.__MacUIRequiredDeviceCapabilities + ), + limitedRepr( + self.__UIRequiredDeviceCapabilities[:20] + if isinstance(self.__UIRequiredDeviceCapabilities, bytes) + else self.__UIRequiredDeviceCapabilities + ), + limitedRepr( + self.__WKRunsIndependentlyOfCompanionApp[:20] + if isinstance(self.__WKRunsIndependentlyOfCompanionApp, bytes) + else self.__WKRunsIndependentlyOfCompanionApp + ), + limitedRepr( + self.__WKWatchOnly[:20] + if isinstance(self.__WKWatchOnly, bytes) + else self.__WKWatchOnly + ), + limitedRepr( + self.__appleWatchEnabled[:20] + if isinstance(self.__appleWatchEnabled, bytes) + else self.__appleWatchEnabled + ), + limitedRepr( + self.__artistId[:20] + if isinstance(self.__artistId, bytes) + else self.__artistId + ), + limitedRepr( + self.__artistName[:20] + if isinstance(self.__artistName, bytes) + else self.__artistName + ), + limitedRepr( + self.__bundleDisplayName[:20] + if isinstance(self.__bundleDisplayName, bytes) + else self.__bundleDisplayName + ), + limitedRepr( + self.__bundleShortVersionString[:20] + if isinstance(self.__bundleShortVersionString, bytes) + else self.__bundleShortVersionString + ), + limitedRepr( + self.__bundleVersion[:20] + if isinstance(self.__bundleVersion, bytes) + else self.__bundleVersion + ), + limitedRepr( + self.__copyright[:20] + if isinstance(self.__copyright, bytes) + else self.__copyright + ), + limitedRepr( + self.__fileExtension[:20] + if isinstance(self.__fileExtension, bytes) + else self.__fileExtension + ), + limitedRepr( + self.__gameCenterEnabled[:20] + if isinstance(self.__gameCenterEnabled, bytes) + else self.__gameCenterEnabled + ), + limitedRepr( + self.__gameCenterEverEnabled[:20] + if isinstance(self.__gameCenterEverEnabled, bytes) + else self.__gameCenterEverEnabled + ), + limitedRepr( + self.__genre[:20] + if isinstance(self.__genre, bytes) + else self.__genre + ), + limitedRepr( + self.__genreId[:20] + if isinstance(self.__genreId, bytes) + else self.__genreId + ), + limitedRepr( + self.__itemId[:20] + if isinstance(self.__itemId, bytes) + else self.__itemId + ), + limitedRepr( + self.__itemName[:20] + if isinstance(self.__itemName, bytes) + else self.__itemName + ), + limitedRepr( + self.__kind[:20] + if isinstance(self.__kind, bytes) + else self.__kind + ), + limitedRepr( + self.__nameTranscriptions[:20] + if isinstance(self.__nameTranscriptions, bytes) + else self.__nameTranscriptions + ), + limitedRepr( + self.__playlistName[:20] + if isinstance(self.__playlistName, bytes) + else self.__playlistName + ), + limitedRepr( + self.__product_type[:20] + if isinstance(self.__product_type, bytes) + else self.__product_type + ), + limitedRepr( + self.__rating[:20] + if isinstance(self.__rating, bytes) + else self.__rating + ), + limitedRepr( + self.__releaseDate[:20] + if isinstance(self.__releaseDate, bytes) + else self.__releaseDate + ), + limitedRepr( + self.__requiresRosetta[:20] + if isinstance(self.__requiresRosetta, bytes) + else self.__requiresRosetta + ), + limitedRepr( + self.__runsOnAppleSilicon[:20] + if isinstance(self.__runsOnAppleSilicon, bytes) + else self.__runsOnAppleSilicon + ), + limitedRepr( + self.__runsOnIntel[:20] + if isinstance(self.__runsOnIntel, bytes) + else self.__runsOnIntel + ), + limitedRepr( + self.__s[:20] if isinstance(self.__s, bytes) else self.__s + ), + limitedRepr( + self.__software_platform[:20] + if isinstance(self.__software_platform, bytes) + else self.__software_platform + ), + limitedRepr( + self.__softwareIcon57x57URL[:20] + if isinstance(self.__softwareIcon57x57URL, bytes) + else self.__softwareIcon57x57URL + ), + limitedRepr( + self.__softwareIconNeedsShine[:20] + if isinstance(self.__softwareIconNeedsShine, bytes) + else self.__softwareIconNeedsShine + ), + limitedRepr( + self.__softwareSupportedDeviceIds[:20] + if isinstance(self.__softwareSupportedDeviceIds, bytes) + else self.__softwareSupportedDeviceIds + ), + limitedRepr( + self.__softwareVersionBundleId[:20] + if isinstance(self.__softwareVersionBundleId, bytes) + else self.__softwareVersionBundleId + ), + limitedRepr( + self.__softwareVersionExternalIdentifier[:20] + if isinstance(self.__softwareVersionExternalIdentifier, bytes) + else self.__softwareVersionExternalIdentifier + ), + limitedRepr( + self.__softwareVersionExternalIdentifiers[:20] + if isinstance(self.__softwareVersionExternalIdentifiers, bytes) + else self.__softwareVersionExternalIdentifiers + ), + limitedRepr( + self.__vendorId[:20] + if isinstance(self.__vendorId, bytes) + else self.__vendorId + ), + limitedRepr( + self.__drmVersionNumber[:20] + if isinstance(self.__drmVersionNumber, bytes) + else self.__drmVersionNumber + ), + limitedRepr( + self.__versionRestrictions[:20] + if isinstance(self.__versionRestrictions, bytes) + else self.__versionRestrictions + ), + limitedRepr( + self.__storeCohort[:20] + if isinstance(self.__storeCohort, bytes) + else self.__storeCohort + ), + limitedRepr( + self.__hasOrEverHasHadIAP[:20] + if isinstance(self.__hasOrEverHasHadIAP, bytes) + else self.__hasOrEverHasHadIAP + ), + ) + + class _asset_info: + + _types_map = { + "file_size": {"type": int, "subtype": None}, + "flavor": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "file_size": { + "required": True, + }, + "flavor": { + "required": True, + }, + } + + def __init__(self, file_size: int = None, flavor: str = None): + pass + self.__file_size = file_size + self.__flavor = flavor + + def _get_file_size(self): + return self.__file_size + + def _set_file_size(self, value): + if not isinstance(value, int): + raise TypeError("file_size must be int") + + self.__file_size = value + + file_size = property(_get_file_size, _set_file_size) + + def _get_flavor(self): + return self.__flavor + + def _set_flavor(self, value): + if not isinstance(value, str): + raise TypeError("flavor must be str") + + self.__flavor = value + + flavor = property(_get_flavor, _set_flavor) + + @staticmethod + def from_dict(d): + v = {} + if "file-size" in d: + v["file_size"] = ( + int.from_dict(d["file-size"]) + if hasattr(int, "from_dict") + else d["file-size"] + ) + if "flavor" in d: + v["flavor"] = ( + str.from_dict(d["flavor"]) + if hasattr(str, "from_dict") + else d["flavor"] + ) + return StoreBuyproductResp._songList._asset_info(**v) + + def as_dict(self): + d = {} + if self.__file_size is not None: + d["file-size"] = ( + self.__file_size.as_dict() + if hasattr(self.__file_size, "as_dict") + else self.__file_size + ) + if self.__flavor is not None: + d["flavor"] = ( + self.__flavor.as_dict() + if hasattr(self.__flavor, "as_dict") + else self.__flavor + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__file_size[:20] + if isinstance(self.__file_size, bytes) + else self.__file_size + ), + limitedRepr( + self.__flavor[:20] + if isinstance(self.__flavor, bytes) + else self.__flavor + ), + ) + + class _chunks: + + _types_map = { + "chunkSize": {"type": int, "subtype": None}, + "hashes": {"type": list, "subtype": str}, + } + _formats_map = {} + _validations_map = { + "chunkSize": { + "required": True, + }, + "hashes": { + "required": True, + }, + } + + def __init__(self, chunkSize: int = None, hashes: List[str] = None): + pass + self.__chunkSize = chunkSize + self.__hashes = hashes + + def _get_chunkSize(self): + return self.__chunkSize + + def _set_chunkSize(self, value): + if not isinstance(value, int): + raise TypeError("chunkSize must be int") + + self.__chunkSize = value + + chunkSize = property(_get_chunkSize, _set_chunkSize) + + def _get_hashes(self): + return self.__hashes + + def _set_hashes(self, value): + if not isinstance(value, list): + raise TypeError("hashes must be list") + if not all(isinstance(i, str) for i in value): + raise TypeError("hashes list values must be str") + + self.__hashes = value + + hashes = property(_get_hashes, _set_hashes) + + @staticmethod + def from_dict(d): + v = {} + if "chunkSize" in d: + v["chunkSize"] = ( + int.from_dict(d["chunkSize"]) + if hasattr(int, "from_dict") + else d["chunkSize"] + ) + if "hashes" in d: + v["hashes"] = [ + str.from_dict(p) if hasattr(str, "from_dict") else p + for p in d["hashes"] + ] + return StoreBuyproductResp._songList._chunks(**v) + + def as_dict(self): + d = {} + if self.__chunkSize is not None: + d["chunkSize"] = ( + self.__chunkSize.as_dict() + if hasattr(self.__chunkSize, "as_dict") + else self.__chunkSize + ) + if self.__hashes is not None: + d["hashes"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__hashes + ] + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__chunkSize[:20] + if isinstance(self.__chunkSize, bytes) + else self.__chunkSize + ), + limitedRepr( + self.__hashes[:20] + if isinstance(self.__hashes, bytes) + else self.__hashes + ), + ) + + class _artwork_urls: + class _default: + + _types_map = { + "url": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "url": { + "required": True, + }, + } + + def __init__(self, url: str = None): + pass + self.__url = url + + def _get_url(self): + return self.__url + + def _set_url(self, value): + if not isinstance(value, str): + raise TypeError("url must be str") + + self.__url = value + + url = property(_get_url, _set_url) + + @staticmethod + def from_dict(d): + v = {} + if "url" in d: + v["url"] = ( + str.from_dict(d["url"]) + if hasattr(str, "from_dict") + else d["url"] + ) + return StoreBuyproductResp._songList._artwork_urls._default(**v) + + def as_dict(self): + d = {} + if self.__url is not None: + d["url"] = ( + self.__url.as_dict() + if hasattr(self.__url, "as_dict") + else self.__url + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__url[:20] + if isinstance(self.__url, bytes) + else self.__url + ) + ) + + _types_map = { + "image_type": {"type": str, "subtype": None}, + "default": {"type": _default, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "image_type": { + "required": True, + }, + "default": { + "required": True, + }, + } + + def __init__(self, image_type: str = None, default: _default = None): + pass + self.__image_type = image_type + self.__default = default + + def _get_image_type(self): + return self.__image_type + + def _set_image_type(self, value): + if not isinstance(value, str): + raise TypeError("image_type must be str") + + self.__image_type = value + + image_type = property(_get_image_type, _set_image_type) + + def _get_default(self): + return self.__default + + def _set_default(self, value): + if not isinstance( + value, StoreBuyproductResp._songList._artwork_urls._default + ): + raise TypeError( + "default must be StoreBuyproductResp._songList._artwork_urls._default" + ) + + self.__default = value + + default = property(_get_default, _set_default) + + @staticmethod + def from_dict(d): + v = {} + if "image-type" in d: + v["image_type"] = ( + str.from_dict(d["image-type"]) + if hasattr(str, "from_dict") + else d["image-type"] + ) + if "default" in d: + v["default"] = ( + StoreBuyproductResp._songList._artwork_urls._default.from_dict( + d["default"] + ) + if hasattr( + StoreBuyproductResp._songList._artwork_urls._default, + "from_dict", + ) + else d["default"] + ) + return StoreBuyproductResp._songList._artwork_urls(**v) + + def as_dict(self): + d = {} + if self.__image_type is not None: + d["image-type"] = ( + self.__image_type.as_dict() + if hasattr(self.__image_type, "as_dict") + else self.__image_type + ) + if self.__default is not None: + d["default"] = ( + self.__default.as_dict() + if hasattr(self.__default, "as_dict") + else self.__default + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__image_type[:20] + if isinstance(self.__image_type, bytes) + else self.__image_type + ), + limitedRepr( + self.__default[:20] + if isinstance(self.__default, bytes) + else self.__default + ), + ) + + class _sinfs: + + _types_map = { + "id": {"type": int, "subtype": None}, + "sinf": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "id": { + "required": True, + }, + "sinf": { + "required": True, + }, + } + + def __init__(self, id: int = None, sinf: str = None): + pass + self.__id = id + self.__sinf = sinf + + def _get_id(self): + return self.__id + + def _set_id(self, value): + if not isinstance(value, int): + raise TypeError("id must be int") + + self.__id = value + + id = property(_get_id, _set_id) + + def _get_sinf(self): + return self.__sinf + + def _set_sinf(self, value): + if not isinstance(value, str): + raise TypeError("sinf must be str") + + self.__sinf = value + + sinf = property(_get_sinf, _set_sinf) + + @staticmethod + def from_dict(d): + v = {} + if "id" in d: + v["id"] = ( + int.from_dict(d["id"]) if hasattr(int, "from_dict") else d["id"] + ) + if "sinf" in d: + v["sinf"] = ( + str.from_dict(d["sinf"]) + if hasattr(str, "from_dict") + else d["sinf"] + ) + return StoreBuyproductResp._songList._sinfs(**v) + + def as_dict(self): + d = {} + if self.__id is not None: + d["id"] = ( + self.__id.as_dict() + if hasattr(self.__id, "as_dict") + else self.__id + ) + if self.__sinf is not None: + d["sinf"] = ( + self.__sinf.as_dict() + if hasattr(self.__sinf, "as_dict") + else self.__sinf + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__id[:20] if isinstance(self.__id, bytes) else self.__id + ), + limitedRepr( + self.__sinf[:20] + if isinstance(self.__sinf, bytes) + else self.__sinf + ), + ) + + _types_map = { + "songId": {"type": int, "subtype": None}, + "URL": {"type": str, "subtype": None}, + "downloadKey": {"type": str, "subtype": None}, + "artworkURL": {"type": str, "subtype": None}, + "artwork_urls": {"type": _artwork_urls, "subtype": None}, + "md5": {"type": str, "subtype": None}, + "chunks": {"type": _chunks, "subtype": None}, + "isStreamable": {"type": bool, "subtype": None}, + "uncompressedSize": {"type": int, "subtype": None}, + "sinfs": {"type": list, "subtype": _sinfs}, + "purchaseDate": {"type": str, "subtype": None}, + "download_id": {"type": str, "subtype": None}, + "is_in_queue": {"type": bool, "subtype": None}, + "asset_info": {"type": _asset_info, "subtype": None}, + "metadata": {"type": _metadata, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "songId": { + "required": True, + }, + "URL": { + "required": True, + }, + "downloadKey": { + "required": True, + }, + "artworkURL": { + "required": True, + }, + "artwork_urls": { + "required": True, + }, + "md5": { + "required": True, + }, + "chunks": { + "required": True, + }, + "isStreamable": { + "required": True, + }, + "uncompressedSize": { + "required": True, + }, + "sinfs": { + "required": True, + }, + "purchaseDate": { + "required": True, + }, + "download_id": { + "required": True, + }, + "is_in_queue": { + "required": True, + }, + "asset_info": { + "required": True, + }, + "metadata": { + "required": True, + }, + } + + def __init__( + self, + songId: int = None, + URL: str = None, + downloadKey: str = None, + artworkURL: str = None, + artwork_urls: _artwork_urls = None, + md5: str = None, + chunks: _chunks = None, + isStreamable: bool = None, + uncompressedSize: int = None, + sinfs: List[_sinfs] = None, + purchaseDate: str = None, + download_id: str = None, + is_in_queue: bool = None, + asset_info: _asset_info = None, + metadata: _metadata = None, + ): + pass + self.__songId = songId + self.__URL = URL + self.__downloadKey = downloadKey + self.__artworkURL = artworkURL + self.__artwork_urls = artwork_urls + self.__md5 = md5 + self.__chunks = chunks + self.__isStreamable = isStreamable + self.__uncompressedSize = uncompressedSize + self.__sinfs = sinfs + self.__purchaseDate = purchaseDate + self.__download_id = download_id + self.__is_in_queue = is_in_queue + self.__asset_info = asset_info + self.__metadata = metadata + + def _get_songId(self): + return self.__songId + + def _set_songId(self, value): + if not isinstance(value, int): + raise TypeError("songId must be int") + + self.__songId = value + + songId = property(_get_songId, _set_songId) + + def _get_URL(self): + return self.__URL + + def _set_URL(self, value): + if not isinstance(value, str): + raise TypeError("URL must be str") + + self.__URL = value + + URL = property(_get_URL, _set_URL) + + def _get_downloadKey(self): + return self.__downloadKey + + def _set_downloadKey(self, value): + if not isinstance(value, str): + raise TypeError("downloadKey must be str") + + self.__downloadKey = value + + downloadKey = property(_get_downloadKey, _set_downloadKey) + + def _get_artworkURL(self): + return self.__artworkURL + + def _set_artworkURL(self, value): + if not isinstance(value, str): + raise TypeError("artworkURL must be str") + + self.__artworkURL = value + + artworkURL = property(_get_artworkURL, _set_artworkURL) + + def _get_artwork_urls(self): + return self.__artwork_urls + + def _set_artwork_urls(self, value): + if not isinstance(value, StoreBuyproductResp._songList._artwork_urls): + raise TypeError( + "artwork_urls must be StoreBuyproductResp._songList._artwork_urls" + ) + + self.__artwork_urls = value + + artwork_urls = property(_get_artwork_urls, _set_artwork_urls) + + def _get_md5(self): + return self.__md5 + + def _set_md5(self, value): + if not isinstance(value, str): + raise TypeError("md5 must be str") + + self.__md5 = value + + md5 = property(_get_md5, _set_md5) + + def _get_chunks(self): + return self.__chunks + + def _set_chunks(self, value): + if not isinstance(value, StoreBuyproductResp._songList._chunks): + raise TypeError("chunks must be StoreBuyproductResp._songList._chunks") + + self.__chunks = value + + chunks = property(_get_chunks, _set_chunks) + + def _get_isStreamable(self): + return self.__isStreamable + + def _set_isStreamable(self, value): + if not isinstance(value, bool): + raise TypeError("isStreamable must be bool") + + self.__isStreamable = value + + isStreamable = property(_get_isStreamable, _set_isStreamable) + + def _get_uncompressedSize(self): + return self.__uncompressedSize + + def _set_uncompressedSize(self, value): + if not isinstance(value, int): + raise TypeError("uncompressedSize must be int") + + self.__uncompressedSize = value + + uncompressedSize = property(_get_uncompressedSize, _set_uncompressedSize) + + def _get_sinfs(self): + return self.__sinfs + + def _set_sinfs(self, value): + if not isinstance(value, list): + raise TypeError("sinfs must be list") + if not all( + isinstance(i, StoreBuyproductResp._songList._sinfs) for i in value + ): + raise TypeError( + "sinfs list values must be StoreBuyproductResp._songList._sinfs" + ) + + self.__sinfs = value + + sinfs = property(_get_sinfs, _set_sinfs) + + def _get_purchaseDate(self): + return self.__purchaseDate + + def _set_purchaseDate(self, value): + if not isinstance(value, str): + raise TypeError("purchaseDate must be str") + + self.__purchaseDate = value + + purchaseDate = property(_get_purchaseDate, _set_purchaseDate) + + def _get_download_id(self): + return self.__download_id + + def _set_download_id(self, value): + if not isinstance(value, str): + raise TypeError("download_id must be str") + + self.__download_id = value + + download_id = property(_get_download_id, _set_download_id) + + def _get_is_in_queue(self): + return self.__is_in_queue + + def _set_is_in_queue(self, value): + if not isinstance(value, bool): + raise TypeError("is_in_queue must be bool") + + self.__is_in_queue = value + + is_in_queue = property(_get_is_in_queue, _set_is_in_queue) + + def _get_asset_info(self): + return self.__asset_info + + def _set_asset_info(self, value): + if not isinstance(value, StoreBuyproductResp._songList._asset_info): + raise TypeError( + "asset_info must be StoreBuyproductResp._songList._asset_info" + ) + + self.__asset_info = value + + asset_info = property(_get_asset_info, _set_asset_info) + + def _get_metadata(self): + return self.__metadata + + def _set_metadata(self, value): + if not isinstance(value, StoreBuyproductResp._songList._metadata): + raise TypeError( + "metadata must be StoreBuyproductResp._songList._metadata" + ) + + self.__metadata = value + + metadata = property(_get_metadata, _set_metadata) + + @staticmethod + def from_dict(d): + v = {} + if "songId" in d: + v["songId"] = ( + int.from_dict(d["songId"]) + if hasattr(int, "from_dict") + else d["songId"] + ) + if "URL" in d: + v["URL"] = ( + str.from_dict(d["URL"]) if hasattr(str, "from_dict") else d["URL"] + ) + if "downloadKey" in d: + v["downloadKey"] = ( + str.from_dict(d["downloadKey"]) + if hasattr(str, "from_dict") + else d["downloadKey"] + ) + if "artworkURL" in d: + v["artworkURL"] = ( + str.from_dict(d["artworkURL"]) + if hasattr(str, "from_dict") + else d["artworkURL"] + ) + if "artwork-urls" in d: + v["artwork_urls"] = ( + StoreBuyproductResp._songList._artwork_urls.from_dict( + d["artwork-urls"] + ) + if hasattr(StoreBuyproductResp._songList._artwork_urls, "from_dict") + else d["artwork-urls"] + ) + if "md5" in d: + v["md5"] = ( + str.from_dict(d["md5"]) if hasattr(str, "from_dict") else d["md5"] + ) + if "chunks" in d: + v["chunks"] = ( + StoreBuyproductResp._songList._chunks.from_dict(d["chunks"]) + if hasattr(StoreBuyproductResp._songList._chunks, "from_dict") + else d["chunks"] + ) + if "isStreamable" in d: + v["isStreamable"] = ( + bool.from_dict(d["isStreamable"]) + if hasattr(bool, "from_dict") + else d["isStreamable"] + ) + if "uncompressedSize" in d: + v["uncompressedSize"] = ( + int.from_dict(d["uncompressedSize"]) + if hasattr(int, "from_dict") + else d["uncompressedSize"] + ) + if "sinfs" in d: + v["sinfs"] = [ + StoreBuyproductResp._songList._sinfs.from_dict(p) + if hasattr(StoreBuyproductResp._songList._sinfs, "from_dict") + else p + for p in d["sinfs"] + ] + if "purchaseDate" in d: + v["purchaseDate"] = ( + str.from_dict(d["purchaseDate"]) + if hasattr(str, "from_dict") + else d["purchaseDate"] + ) + if "download-id" in d: + v["download_id"] = ( + str.from_dict(d["download-id"]) + if hasattr(str, "from_dict") + else d["download-id"] + ) + if "is-in-queue" in d: + v["is_in_queue"] = ( + bool.from_dict(d["is-in-queue"]) + if hasattr(bool, "from_dict") + else d["is-in-queue"] + ) + if "asset-info" in d: + v["asset_info"] = ( + StoreBuyproductResp._songList._asset_info.from_dict(d["asset-info"]) + if hasattr(StoreBuyproductResp._songList._asset_info, "from_dict") + else d["asset-info"] + ) + if "metadata" in d: + v["metadata"] = ( + StoreBuyproductResp._songList._metadata.from_dict(d["metadata"]) + if hasattr(StoreBuyproductResp._songList._metadata, "from_dict") + else d["metadata"] + ) + return StoreBuyproductResp._songList(**v) + + def as_dict(self): + d = {} + if self.__songId is not None: + d["songId"] = ( + self.__songId.as_dict() + if hasattr(self.__songId, "as_dict") + else self.__songId + ) + if self.__URL is not None: + d["URL"] = ( + self.__URL.as_dict() + if hasattr(self.__URL, "as_dict") + else self.__URL + ) + if self.__downloadKey is not None: + d["downloadKey"] = ( + self.__downloadKey.as_dict() + if hasattr(self.__downloadKey, "as_dict") + else self.__downloadKey + ) + if self.__artworkURL is not None: + d["artworkURL"] = ( + self.__artworkURL.as_dict() + if hasattr(self.__artworkURL, "as_dict") + else self.__artworkURL + ) + if self.__artwork_urls is not None: + d["artwork-urls"] = ( + self.__artwork_urls.as_dict() + if hasattr(self.__artwork_urls, "as_dict") + else self.__artwork_urls + ) + if self.__md5 is not None: + d["md5"] = ( + self.__md5.as_dict() + if hasattr(self.__md5, "as_dict") + else self.__md5 + ) + if self.__chunks is not None: + d["chunks"] = ( + self.__chunks.as_dict() + if hasattr(self.__chunks, "as_dict") + else self.__chunks + ) + if self.__isStreamable is not None: + d["isStreamable"] = ( + self.__isStreamable.as_dict() + if hasattr(self.__isStreamable, "as_dict") + else self.__isStreamable + ) + if self.__uncompressedSize is not None: + d["uncompressedSize"] = ( + self.__uncompressedSize.as_dict() + if hasattr(self.__uncompressedSize, "as_dict") + else self.__uncompressedSize + ) + if self.__sinfs is not None: + d["sinfs"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__sinfs + ] + if self.__purchaseDate is not None: + d["purchaseDate"] = ( + self.__purchaseDate.as_dict() + if hasattr(self.__purchaseDate, "as_dict") + else self.__purchaseDate + ) + if self.__download_id is not None: + d["download-id"] = ( + self.__download_id.as_dict() + if hasattr(self.__download_id, "as_dict") + else self.__download_id + ) + if self.__is_in_queue is not None: + d["is-in-queue"] = ( + self.__is_in_queue.as_dict() + if hasattr(self.__is_in_queue, "as_dict") + else self.__is_in_queue + ) + if self.__asset_info is not None: + d["asset-info"] = ( + self.__asset_info.as_dict() + if hasattr(self.__asset_info, "as_dict") + else self.__asset_info + ) + if self.__metadata is not None: + d["metadata"] = ( + self.__metadata.as_dict() + if hasattr(self.__metadata, "as_dict") + else self.__metadata + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__songId[:20] + if isinstance(self.__songId, bytes) + else self.__songId + ), + limitedRepr( + self.__URL[:20] if isinstance(self.__URL, bytes) else self.__URL + ), + limitedRepr( + self.__downloadKey[:20] + if isinstance(self.__downloadKey, bytes) + else self.__downloadKey + ), + limitedRepr( + self.__artworkURL[:20] + if isinstance(self.__artworkURL, bytes) + else self.__artworkURL + ), + limitedRepr( + self.__artwork_urls[:20] + if isinstance(self.__artwork_urls, bytes) + else self.__artwork_urls + ), + limitedRepr( + self.__md5[:20] if isinstance(self.__md5, bytes) else self.__md5 + ), + limitedRepr( + self.__chunks[:20] + if isinstance(self.__chunks, bytes) + else self.__chunks + ), + limitedRepr( + self.__isStreamable[:20] + if isinstance(self.__isStreamable, bytes) + else self.__isStreamable + ), + limitedRepr( + self.__uncompressedSize[:20] + if isinstance(self.__uncompressedSize, bytes) + else self.__uncompressedSize + ), + limitedRepr( + self.__sinfs[:20] + if isinstance(self.__sinfs, bytes) + else self.__sinfs + ), + limitedRepr( + self.__purchaseDate[:20] + if isinstance(self.__purchaseDate, bytes) + else self.__purchaseDate + ), + limitedRepr( + self.__download_id[:20] + if isinstance(self.__download_id, bytes) + else self.__download_id + ), + limitedRepr( + self.__is_in_queue[:20] + if isinstance(self.__is_in_queue, bytes) + else self.__is_in_queue + ), + limitedRepr( + self.__asset_info[:20] + if isinstance(self.__asset_info, bytes) + else self.__asset_info + ), + limitedRepr( + self.__metadata[:20] + if isinstance(self.__metadata, bytes) + else self.__metadata + ), + ) + + class _subscriptionStatus: + class _family: + + _types_map = { + "hasFamily": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "hasFamily": { + "required": True, + }, + } + + def __init__(self, hasFamily: bool = None): + pass + self.__hasFamily = hasFamily + + def _get_hasFamily(self): + return self.__hasFamily + + def _set_hasFamily(self, value): + if not isinstance(value, bool): + raise TypeError("hasFamily must be bool") + + self.__hasFamily = value + + hasFamily = property(_get_hasFamily, _set_hasFamily) + + @staticmethod + def from_dict(d): + v = {} + if "hasFamily" in d: + v["hasFamily"] = ( + bool.from_dict(d["hasFamily"]) + if hasattr(bool, "from_dict") + else d["hasFamily"] + ) + return StoreBuyproductResp._subscriptionStatus._family(**v) + + def as_dict(self): + d = {} + if self.__hasFamily is not None: + d["hasFamily"] = ( + self.__hasFamily.as_dict() + if hasattr(self.__hasFamily, "as_dict") + else self.__hasFamily + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__hasFamily[:20] + if isinstance(self.__hasFamily, bytes) + else self.__hasFamily + ) + ) + + class _music: + + _types_map = { + "status": {"type": str, "subtype": None}, + "reason": {"type": str, "subtype": None}, + "isAdmin": {"type": bool, "subtype": None}, + "isNotEligibleForFreeTrial": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "status": { + "required": True, + }, + "reason": { + "required": True, + }, + "isAdmin": { + "required": True, + }, + "isNotEligibleForFreeTrial": { + "required": True, + }, + } + + def __init__( + self, + status: str = None, + reason: str = None, + isAdmin: bool = None, + isNotEligibleForFreeTrial: bool = None, + ): + pass + self.__status = status + self.__reason = reason + self.__isAdmin = isAdmin + self.__isNotEligibleForFreeTrial = isNotEligibleForFreeTrial + + def _get_status(self): + return self.__status + + def _set_status(self, value): + if not isinstance(value, str): + raise TypeError("status must be str") + + self.__status = value + + status = property(_get_status, _set_status) + + def _get_reason(self): + return self.__reason + + def _set_reason(self, value): + if not isinstance(value, str): + raise TypeError("reason must be str") + + self.__reason = value + + reason = property(_get_reason, _set_reason) + + def _get_isAdmin(self): + return self.__isAdmin + + def _set_isAdmin(self, value): + if not isinstance(value, bool): + raise TypeError("isAdmin must be bool") + + self.__isAdmin = value + + isAdmin = property(_get_isAdmin, _set_isAdmin) + + def _get_isNotEligibleForFreeTrial(self): + return self.__isNotEligibleForFreeTrial + + def _set_isNotEligibleForFreeTrial(self, value): + if not isinstance(value, bool): + raise TypeError("isNotEligibleForFreeTrial must be bool") + + self.__isNotEligibleForFreeTrial = value + + isNotEligibleForFreeTrial = property( + _get_isNotEligibleForFreeTrial, _set_isNotEligibleForFreeTrial + ) + + @staticmethod + def from_dict(d): + v = {} + if "status" in d: + v["status"] = ( + str.from_dict(d["status"]) + if hasattr(str, "from_dict") + else d["status"] + ) + if "reason" in d: + v["reason"] = ( + str.from_dict(d["reason"]) + if hasattr(str, "from_dict") + else d["reason"] + ) + if "isAdmin" in d: + v["isAdmin"] = ( + bool.from_dict(d["isAdmin"]) + if hasattr(bool, "from_dict") + else d["isAdmin"] + ) + if "isNotEligibleForFreeTrial" in d: + v["isNotEligibleForFreeTrial"] = ( + bool.from_dict(d["isNotEligibleForFreeTrial"]) + if hasattr(bool, "from_dict") + else d["isNotEligibleForFreeTrial"] + ) + return StoreBuyproductResp._subscriptionStatus._music(**v) + + def as_dict(self): + d = {} + if self.__status is not None: + d["status"] = ( + self.__status.as_dict() + if hasattr(self.__status, "as_dict") + else self.__status + ) + if self.__reason is not None: + d["reason"] = ( + self.__reason.as_dict() + if hasattr(self.__reason, "as_dict") + else self.__reason + ) + if self.__isAdmin is not None: + d["isAdmin"] = ( + self.__isAdmin.as_dict() + if hasattr(self.__isAdmin, "as_dict") + else self.__isAdmin + ) + if self.__isNotEligibleForFreeTrial is not None: + d["isNotEligibleForFreeTrial"] = ( + self.__isNotEligibleForFreeTrial.as_dict() + if hasattr(self.__isNotEligibleForFreeTrial, "as_dict") + else self.__isNotEligibleForFreeTrial + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__status[:20] + if isinstance(self.__status, bytes) + else self.__status + ), + limitedRepr( + self.__reason[:20] + if isinstance(self.__reason, bytes) + else self.__reason + ), + limitedRepr( + self.__isAdmin[:20] + if isinstance(self.__isAdmin, bytes) + else self.__isAdmin + ), + limitedRepr( + self.__isNotEligibleForFreeTrial[:20] + if isinstance(self.__isNotEligibleForFreeTrial, bytes) + else self.__isNotEligibleForFreeTrial + ), + ) + + class _terms: + + _types_map = { + "type": {"type": str, "subtype": None}, + "latestTerms": {"type": int, "subtype": None}, + "agreedToTerms": {"type": int, "subtype": None}, + "source": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "type": { + "required": True, + }, + "latestTerms": { + "required": True, + }, + "agreedToTerms": { + "required": True, + }, + "source": { + "required": True, + }, + } + + def __init__( + self, + type: str = None, + latestTerms: int = None, + agreedToTerms: int = None, + source: str = None, + ): + pass + self.__type = type + self.__latestTerms = latestTerms + self.__agreedToTerms = agreedToTerms + self.__source = source + + def _get_type(self): + return self.__type + + def _set_type(self, value): + if not isinstance(value, str): + raise TypeError("type must be str") + + self.__type = value + + type = property(_get_type, _set_type) + + def _get_latestTerms(self): + return self.__latestTerms + + def _set_latestTerms(self, value): + if not isinstance(value, int): + raise TypeError("latestTerms must be int") + + self.__latestTerms = value + + latestTerms = property(_get_latestTerms, _set_latestTerms) + + def _get_agreedToTerms(self): + return self.__agreedToTerms + + def _set_agreedToTerms(self, value): + if not isinstance(value, int): + raise TypeError("agreedToTerms must be int") + + self.__agreedToTerms = value + + agreedToTerms = property(_get_agreedToTerms, _set_agreedToTerms) + + def _get_source(self): + return self.__source + + def _set_source(self, value): + if not isinstance(value, str): + raise TypeError("source must be str") + + self.__source = value + + source = property(_get_source, _set_source) + + @staticmethod + def from_dict(d): + v = {} + if "type" in d: + v["type"] = ( + str.from_dict(d["type"]) + if hasattr(str, "from_dict") + else d["type"] + ) + if "latestTerms" in d: + v["latestTerms"] = ( + int.from_dict(d["latestTerms"]) + if hasattr(int, "from_dict") + else d["latestTerms"] + ) + if "agreedToTerms" in d: + v["agreedToTerms"] = ( + int.from_dict(d["agreedToTerms"]) + if hasattr(int, "from_dict") + else d["agreedToTerms"] + ) + if "source" in d: + v["source"] = ( + str.from_dict(d["source"]) + if hasattr(str, "from_dict") + else d["source"] + ) + return StoreBuyproductResp._subscriptionStatus._terms(**v) + + def as_dict(self): + d = {} + if self.__type is not None: + d["type"] = ( + self.__type.as_dict() + if hasattr(self.__type, "as_dict") + else self.__type + ) + if self.__latestTerms is not None: + d["latestTerms"] = ( + self.__latestTerms.as_dict() + if hasattr(self.__latestTerms, "as_dict") + else self.__latestTerms + ) + if self.__agreedToTerms is not None: + d["agreedToTerms"] = ( + self.__agreedToTerms.as_dict() + if hasattr(self.__agreedToTerms, "as_dict") + else self.__agreedToTerms + ) + if self.__source is not None: + d["source"] = ( + self.__source.as_dict() + if hasattr(self.__source, "as_dict") + else self.__source + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__type[:20] + if isinstance(self.__type, bytes) + else self.__type + ), + limitedRepr( + self.__latestTerms[:20] + if isinstance(self.__latestTerms, bytes) + else self.__latestTerms + ), + limitedRepr( + self.__agreedToTerms[:20] + if isinstance(self.__agreedToTerms, bytes) + else self.__agreedToTerms + ), + limitedRepr( + self.__source[:20] + if isinstance(self.__source, bytes) + else self.__source + ), + ) + + class _account: + + _types_map = { + "isMinor": {"type": bool, "subtype": None}, + "suspectUnderage": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "isMinor": { + "required": True, + }, + "suspectUnderage": { + "required": True, + }, + } + + def __init__(self, isMinor: bool = None, suspectUnderage: bool = None): + pass + self.__isMinor = isMinor + self.__suspectUnderage = suspectUnderage + + def _get_isMinor(self): + return self.__isMinor + + def _set_isMinor(self, value): + if not isinstance(value, bool): + raise TypeError("isMinor must be bool") + + self.__isMinor = value + + isMinor = property(_get_isMinor, _set_isMinor) + + def _get_suspectUnderage(self): + return self.__suspectUnderage + + def _set_suspectUnderage(self, value): + if not isinstance(value, bool): + raise TypeError("suspectUnderage must be bool") + + self.__suspectUnderage = value + + suspectUnderage = property(_get_suspectUnderage, _set_suspectUnderage) + + @staticmethod + def from_dict(d): + v = {} + if "isMinor" in d: + v["isMinor"] = ( + bool.from_dict(d["isMinor"]) + if hasattr(bool, "from_dict") + else d["isMinor"] + ) + if "suspectUnderage" in d: + v["suspectUnderage"] = ( + bool.from_dict(d["suspectUnderage"]) + if hasattr(bool, "from_dict") + else d["suspectUnderage"] + ) + return StoreBuyproductResp._subscriptionStatus._account(**v) + + def as_dict(self): + d = {} + if self.__isMinor is not None: + d["isMinor"] = ( + self.__isMinor.as_dict() + if hasattr(self.__isMinor, "as_dict") + else self.__isMinor + ) + if self.__suspectUnderage is not None: + d["suspectUnderage"] = ( + self.__suspectUnderage.as_dict() + if hasattr(self.__suspectUnderage, "as_dict") + else self.__suspectUnderage + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__isMinor[:20] + if isinstance(self.__isMinor, bytes) + else self.__isMinor + ), + limitedRepr( + self.__suspectUnderage[:20] + if isinstance(self.__suspectUnderage, bytes) + else self.__suspectUnderage + ), + ) + + _types_map = { + "music": {"type": _music, "subtype": None}, + "terms": {"type": list, "subtype": _terms}, + "account": {"type": _account, "subtype": None}, + "family": {"type": _family, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "music": { + "required": True, + }, + "terms": { + "required": True, + }, + "account": { + "required": True, + }, + "family": { + "required": True, + }, + } + + def __init__( + self, + music: _music = None, + terms: List[_terms] = None, + account: _account = None, + family: _family = None, + ): + pass + self.__music = music + self.__terms = terms + self.__account = account + self.__family = family + + def _get_music(self): + return self.__music + + def _set_music(self, value): + if not isinstance(value, StoreBuyproductResp._subscriptionStatus._music): + raise TypeError( + "music must be StoreBuyproductResp._subscriptionStatus._music" + ) + + self.__music = value + + music = property(_get_music, _set_music) + + def _get_terms(self): + return self.__terms + + def _set_terms(self, value): + if not isinstance(value, list): + raise TypeError("terms must be list") + if not all( + isinstance(i, StoreBuyproductResp._subscriptionStatus._terms) + for i in value + ): + raise TypeError( + "terms list values must be StoreBuyproductResp._subscriptionStatus._terms" + ) + + self.__terms = value + + terms = property(_get_terms, _set_terms) + + def _get_account(self): + return self.__account + + def _set_account(self, value): + if not isinstance(value, StoreBuyproductResp._subscriptionStatus._account): + raise TypeError( + "account must be StoreBuyproductResp._subscriptionStatus._account" + ) + + self.__account = value + + account = property(_get_account, _set_account) + + def _get_family(self): + return self.__family + + def _set_family(self, value): + if not isinstance(value, StoreBuyproductResp._subscriptionStatus._family): + raise TypeError( + "family must be StoreBuyproductResp._subscriptionStatus._family" + ) + + self.__family = value + + family = property(_get_family, _set_family) + + @staticmethod + def from_dict(d): + v = {} + if "music" in d: + v["music"] = ( + StoreBuyproductResp._subscriptionStatus._music.from_dict(d["music"]) + if hasattr( + StoreBuyproductResp._subscriptionStatus._music, "from_dict" + ) + else d["music"] + ) + if "terms" in d: + v["terms"] = [ + StoreBuyproductResp._subscriptionStatus._terms.from_dict(p) + if hasattr( + StoreBuyproductResp._subscriptionStatus._terms, "from_dict" + ) + else p + for p in d["terms"] + ] + if "account" in d: + v["account"] = ( + StoreBuyproductResp._subscriptionStatus._account.from_dict( + d["account"] + ) + if hasattr( + StoreBuyproductResp._subscriptionStatus._account, "from_dict" + ) + else d["account"] + ) + if "family" in d: + v["family"] = ( + StoreBuyproductResp._subscriptionStatus._family.from_dict( + d["family"] + ) + if hasattr( + StoreBuyproductResp._subscriptionStatus._family, "from_dict" + ) + else d["family"] + ) + return StoreBuyproductResp._subscriptionStatus(**v) + + def as_dict(self): + d = {} + if self.__music is not None: + d["music"] = ( + self.__music.as_dict() + if hasattr(self.__music, "as_dict") + else self.__music + ) + if self.__terms is not None: + d["terms"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__terms + ] + if self.__account is not None: + d["account"] = ( + self.__account.as_dict() + if hasattr(self.__account, "as_dict") + else self.__account + ) + if self.__family is not None: + d["family"] = ( + self.__family.as_dict() + if hasattr(self.__family, "as_dict") + else self.__family + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__music[:20] + if isinstance(self.__music, bytes) + else self.__music + ), + limitedRepr( + self.__terms[:20] + if isinstance(self.__terms, bytes) + else self.__terms + ), + limitedRepr( + self.__account[:20] + if isinstance(self.__account, bytes) + else self.__account + ), + limitedRepr( + self.__family[:20] + if isinstance(self.__family, bytes) + else self.__family + ), + ) + + class _download_queue_info: + + _types_map = { + "download_queue_item_count": {"type": int, "subtype": None}, + "dsid": {"type": int, "subtype": None}, + "is_auto_download_machine": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "download_queue_item_count": { + "required": True, + }, + "dsid": { + "required": True, + }, + "is_auto_download_machine": { + "required": True, + }, + } + + def __init__( + self, + download_queue_item_count: int = None, + dsid: int = None, + is_auto_download_machine: bool = None, + ): + pass + self.__download_queue_item_count = download_queue_item_count + self.__dsid = dsid + self.__is_auto_download_machine = is_auto_download_machine + + def _get_download_queue_item_count(self): + return self.__download_queue_item_count + + def _set_download_queue_item_count(self, value): + if not isinstance(value, int): + raise TypeError("download_queue_item_count must be int") + + self.__download_queue_item_count = value + + download_queue_item_count = property( + _get_download_queue_item_count, _set_download_queue_item_count + ) + + def _get_dsid(self): + return self.__dsid + + def _set_dsid(self, value): + if not isinstance(value, int): + raise TypeError("dsid must be int") + + self.__dsid = value + + dsid = property(_get_dsid, _set_dsid) + + def _get_is_auto_download_machine(self): + return self.__is_auto_download_machine + + def _set_is_auto_download_machine(self, value): + if not isinstance(value, bool): + raise TypeError("is_auto_download_machine must be bool") + + self.__is_auto_download_machine = value + + is_auto_download_machine = property( + _get_is_auto_download_machine, _set_is_auto_download_machine + ) + + @staticmethod + def from_dict(d): + v = {} + if "download-queue-item-count" in d: + v["download_queue_item_count"] = ( + int.from_dict(d["download-queue-item-count"]) + if hasattr(int, "from_dict") + else d["download-queue-item-count"] + ) + if "dsid" in d: + v["dsid"] = ( + int.from_dict(d["dsid"]) if hasattr(int, "from_dict") else d["dsid"] + ) + if "is-auto-download-machine" in d: + v["is_auto_download_machine"] = ( + bool.from_dict(d["is-auto-download-machine"]) + if hasattr(bool, "from_dict") + else d["is-auto-download-machine"] + ) + return StoreBuyproductResp._download_queue_info(**v) + + def as_dict(self): + d = {} + if self.__download_queue_item_count is not None: + d["download-queue-item-count"] = ( + self.__download_queue_item_count.as_dict() + if hasattr(self.__download_queue_item_count, "as_dict") + else self.__download_queue_item_count + ) + if self.__dsid is not None: + d["dsid"] = ( + self.__dsid.as_dict() + if hasattr(self.__dsid, "as_dict") + else self.__dsid + ) + if self.__is_auto_download_machine is not None: + d["is-auto-download-machine"] = ( + self.__is_auto_download_machine.as_dict() + if hasattr(self.__is_auto_download_machine, "as_dict") + else self.__is_auto_download_machine + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__download_queue_item_count[:20] + if isinstance(self.__download_queue_item_count, bytes) + else self.__download_queue_item_count + ), + limitedRepr( + self.__dsid[:20] if isinstance(self.__dsid, bytes) else self.__dsid + ), + limitedRepr( + self.__is_auto_download_machine[:20] + if isinstance(self.__is_auto_download_machine, bytes) + else self.__is_auto_download_machine + ), + ) + + class _metrics: + + _types_map = { + "itemIds": {"type": list, "subtype": int}, + "price": {"type": int, "subtype": None}, + "priceType": {"type": str, "subtype": None}, + "productTypes": {"type": list, "subtype": str}, + "mtApp": {"type": str, "subtype": None}, + "mtClientId": {"type": str, "subtype": None}, + "mtEventTime": {"type": str, "subtype": None}, + "mtPageId": {"type": str, "subtype": None}, + "mtPageType": {"type": str, "subtype": None}, + "mtPrevPage": {"type": str, "subtype": None}, + "mtRequestId": {"type": str, "subtype": None}, + "mtTopic": {"type": str, "subtype": None}, + "currency": {"type": str, "subtype": None}, + "exchangeRateToUSD": {"type": float, "subtype": None}, + "commerceEvent_purchase_priceType": {"type": str, "subtype": None}, + "commerceEvent_storeFrontId": {"type": str, "subtype": None}, + "commerceEvent_result_resultType": {"type": int, "subtype": None}, + "commerceEvent_flowType": {"type": int, "subtype": None}, + "commerceEvent_flowStep": {"type": int, "subtype": None}, + "dialogId": {"type": str, "subtype": None}, + "message": {"type": str, "subtype": None}, + "messageCode": {"type": str, "subtype": None}, + "options": {"type": list, "subtype": str}, + "actionUrl": {"type": str, "subtype": None}, + "asnState": {"type": int, "subtype": None}, + "eventType": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "itemIds": { + "required": False, + }, + "price": { + "required": False, + }, + "priceType": { + "required": False, + }, + "productTypes": { + "required": False, + }, + "mtApp": { + "required": True, + }, + "mtClientId": { + "required": True, + }, + "mtEventTime": { + "required": True, + }, + "mtPageId": { + "required": True, + }, + "mtPageType": { + "required": True, + }, + "mtPrevPage": { + "required": True, + }, + "mtRequestId": { + "required": True, + }, + "mtTopic": { + "required": True, + }, + "currency": { + "required": False, + }, + "exchangeRateToUSD": { + "required": False, + }, + "commerceEvent_purchase_priceType": { + "required": False, + }, + "commerceEvent_storeFrontId": { + "required": False, + }, + "commerceEvent_result_resultType": { + "required": False, + }, + "commerceEvent_flowType": { + "required": False, + }, + "commerceEvent_flowStep": { + "required": False, + }, + "dialogId": { + "required": False, + }, + "message": { + "required": False, + }, + "messageCode": { + "required": False, + }, + "options": { + "required": False, + }, + "actionUrl": { + "required": False, + }, + "asnState": { + "required": False, + }, + "eventType": { + "required": False, + }, + } + + def __init__( + self, + itemIds: List[int] = None, + price: int = None, + priceType: str = None, + productTypes: List[str] = None, + mtApp: str = None, + mtClientId: str = None, + mtEventTime: str = None, + mtPageId: str = None, + mtPageType: str = None, + mtPrevPage: str = None, + mtRequestId: str = None, + mtTopic: str = None, + currency: str = None, + exchangeRateToUSD: float = None, + commerceEvent_purchase_priceType: str = None, + commerceEvent_storeFrontId: str = None, + commerceEvent_result_resultType: int = None, + commerceEvent_flowType: int = None, + commerceEvent_flowStep: int = None, + dialogId: str = None, + message: str = None, + messageCode: str = None, + options: List[str] = None, + actionUrl: str = None, + asnState: int = None, + eventType: str = None, + ): + pass + self.__itemIds = itemIds + self.__price = price + self.__priceType = priceType + self.__productTypes = productTypes + self.__mtApp = mtApp + self.__mtClientId = mtClientId + self.__mtEventTime = mtEventTime + self.__mtPageId = mtPageId + self.__mtPageType = mtPageType + self.__mtPrevPage = mtPrevPage + self.__mtRequestId = mtRequestId + self.__mtTopic = mtTopic + self.__currency = currency + self.__exchangeRateToUSD = exchangeRateToUSD + self.__commerceEvent_purchase_priceType = commerceEvent_purchase_priceType + self.__commerceEvent_storeFrontId = commerceEvent_storeFrontId + self.__commerceEvent_result_resultType = commerceEvent_result_resultType + self.__commerceEvent_flowType = commerceEvent_flowType + self.__commerceEvent_flowStep = commerceEvent_flowStep + self.__dialogId = dialogId + self.__message = message + self.__messageCode = messageCode + self.__options = options + self.__actionUrl = actionUrl + self.__asnState = asnState + self.__eventType = eventType + + def _get_itemIds(self): + return self.__itemIds + + def _set_itemIds(self, value): + if value is not None and not isinstance(value, list): + raise TypeError("itemIds must be list") + if value is not None and not all(isinstance(i, int) for i in value): + raise TypeError("itemIds list values must be int") + + self.__itemIds = value + + itemIds = property(_get_itemIds, _set_itemIds) + + def _get_price(self): + return self.__price + + def _set_price(self, value): + if value is not None and not isinstance(value, int): + raise TypeError("price must be int") + + self.__price = value + + price = property(_get_price, _set_price) + + def _get_priceType(self): + return self.__priceType + + def _set_priceType(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("priceType must be str") + + self.__priceType = value + + priceType = property(_get_priceType, _set_priceType) + + def _get_productTypes(self): + return self.__productTypes + + def _set_productTypes(self, value): + if value is not None and not isinstance(value, list): + raise TypeError("productTypes must be list") + if value is not None and not all(isinstance(i, str) for i in value): + raise TypeError("productTypes list values must be str") + + self.__productTypes = value + + productTypes = property(_get_productTypes, _set_productTypes) + + def _get_mtApp(self): + return self.__mtApp + + def _set_mtApp(self, value): + if not isinstance(value, str): + raise TypeError("mtApp must be str") + + self.__mtApp = value + + mtApp = property(_get_mtApp, _set_mtApp) + + def _get_mtClientId(self): + return self.__mtClientId + + def _set_mtClientId(self, value): + if not isinstance(value, str): + raise TypeError("mtClientId must be str") + + self.__mtClientId = value + + mtClientId = property(_get_mtClientId, _set_mtClientId) + + def _get_mtEventTime(self): + return self.__mtEventTime + + def _set_mtEventTime(self, value): + if not isinstance(value, str): + raise TypeError("mtEventTime must be str") + + self.__mtEventTime = value + + mtEventTime = property(_get_mtEventTime, _set_mtEventTime) + + def _get_mtPageId(self): + return self.__mtPageId + + def _set_mtPageId(self, value): + if not isinstance(value, str): + raise TypeError("mtPageId must be str") + + self.__mtPageId = value + + mtPageId = property(_get_mtPageId, _set_mtPageId) + + def _get_mtPageType(self): + return self.__mtPageType + + def _set_mtPageType(self, value): + if not isinstance(value, str): + raise TypeError("mtPageType must be str") + + self.__mtPageType = value + + mtPageType = property(_get_mtPageType, _set_mtPageType) + + def _get_mtPrevPage(self): + return self.__mtPrevPage + + def _set_mtPrevPage(self, value): + if not isinstance(value, str): + raise TypeError("mtPrevPage must be str") + + self.__mtPrevPage = value + + mtPrevPage = property(_get_mtPrevPage, _set_mtPrevPage) + + def _get_mtRequestId(self): + return self.__mtRequestId + + def _set_mtRequestId(self, value): + if not isinstance(value, str): + raise TypeError("mtRequestId must be str") + + self.__mtRequestId = value + + mtRequestId = property(_get_mtRequestId, _set_mtRequestId) + + def _get_mtTopic(self): + return self.__mtTopic + + def _set_mtTopic(self, value): + if not isinstance(value, str): + raise TypeError("mtTopic must be str") + + self.__mtTopic = value + + mtTopic = property(_get_mtTopic, _set_mtTopic) + + def _get_currency(self): + return self.__currency + + def _set_currency(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("currency must be str") + + self.__currency = value + + currency = property(_get_currency, _set_currency) + + def _get_exchangeRateToUSD(self): + return self.__exchangeRateToUSD + + def _set_exchangeRateToUSD(self, value): + if value is not None and not isinstance(value, float): + raise TypeError("exchangeRateToUSD must be float") + + self.__exchangeRateToUSD = value + + exchangeRateToUSD = property(_get_exchangeRateToUSD, _set_exchangeRateToUSD) + + def _get_commerceEvent_purchase_priceType(self): + return self.__commerceEvent_purchase_priceType + + def _set_commerceEvent_purchase_priceType(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("commerceEvent_purchase_priceType must be str") + + self.__commerceEvent_purchase_priceType = value + + commerceEvent_purchase_priceType = property( + _get_commerceEvent_purchase_priceType, _set_commerceEvent_purchase_priceType + ) + + def _get_commerceEvent_storeFrontId(self): + return self.__commerceEvent_storeFrontId + + def _set_commerceEvent_storeFrontId(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("commerceEvent_storeFrontId must be str") + + self.__commerceEvent_storeFrontId = value + + commerceEvent_storeFrontId = property( + _get_commerceEvent_storeFrontId, _set_commerceEvent_storeFrontId + ) + + def _get_commerceEvent_result_resultType(self): + return self.__commerceEvent_result_resultType + + def _set_commerceEvent_result_resultType(self, value): + if value is not None and not isinstance(value, int): + raise TypeError("commerceEvent_result_resultType must be int") + + self.__commerceEvent_result_resultType = value + + commerceEvent_result_resultType = property( + _get_commerceEvent_result_resultType, _set_commerceEvent_result_resultType + ) + + def _get_commerceEvent_flowType(self): + return self.__commerceEvent_flowType + + def _set_commerceEvent_flowType(self, value): + if value is not None and not isinstance(value, int): + raise TypeError("commerceEvent_flowType must be int") + + self.__commerceEvent_flowType = value + + commerceEvent_flowType = property( + _get_commerceEvent_flowType, _set_commerceEvent_flowType + ) + + def _get_commerceEvent_flowStep(self): + return self.__commerceEvent_flowStep + + def _set_commerceEvent_flowStep(self, value): + if value is not None and not isinstance(value, int): + raise TypeError("commerceEvent_flowStep must be int") + + self.__commerceEvent_flowStep = value + + commerceEvent_flowStep = property( + _get_commerceEvent_flowStep, _set_commerceEvent_flowStep + ) + + def _get_dialogId(self): + return self.__dialogId + + def _set_dialogId(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("dialogId must be str") + + self.__dialogId = value + + dialogId = property(_get_dialogId, _set_dialogId) + + def _get_message(self): + return self.__message + + def _set_message(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("message must be str") + + self.__message = value + + message = property(_get_message, _set_message) + + def _get_messageCode(self): + return self.__messageCode + + def _set_messageCode(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("messageCode must be str") + + self.__messageCode = value + + messageCode = property(_get_messageCode, _set_messageCode) + + def _get_options(self): + return self.__options + + def _set_options(self, value): + if value is not None and not isinstance(value, list): + raise TypeError("options must be list") + if value is not None and not all(isinstance(i, str) for i in value): + raise TypeError("options list values must be str") + + self.__options = value + + options = property(_get_options, _set_options) + + def _get_actionUrl(self): + return self.__actionUrl + + def _set_actionUrl(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("actionUrl must be str") + + self.__actionUrl = value + + actionUrl = property(_get_actionUrl, _set_actionUrl) + + def _get_asnState(self): + return self.__asnState + + def _set_asnState(self, value): + if value is not None and not isinstance(value, int): + raise TypeError("asnState must be int") + + self.__asnState = value + + asnState = property(_get_asnState, _set_asnState) + + def _get_eventType(self): + return self.__eventType + + def _set_eventType(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("eventType must be str") + + self.__eventType = value + + eventType = property(_get_eventType, _set_eventType) + + @staticmethod + def from_dict(d): + v = {} + if "itemIds" in d: + v["itemIds"] = [ + int.from_dict(p) if hasattr(int, "from_dict") else p + for p in d["itemIds"] + ] + if "price" in d: + v["price"] = ( + int.from_dict(d["price"]) + if hasattr(int, "from_dict") + else d["price"] + ) + if "priceType" in d: + v["priceType"] = ( + str.from_dict(d["priceType"]) + if hasattr(str, "from_dict") + else d["priceType"] + ) + if "productTypes" in d: + v["productTypes"] = [ + str.from_dict(p) if hasattr(str, "from_dict") else p + for p in d["productTypes"] + ] + if "mtApp" in d: + v["mtApp"] = ( + str.from_dict(d["mtApp"]) + if hasattr(str, "from_dict") + else d["mtApp"] + ) + if "mtClientId" in d: + v["mtClientId"] = ( + str.from_dict(d["mtClientId"]) + if hasattr(str, "from_dict") + else d["mtClientId"] + ) + if "mtEventTime" in d: + v["mtEventTime"] = ( + str.from_dict(d["mtEventTime"]) + if hasattr(str, "from_dict") + else d["mtEventTime"] + ) + if "mtPageId" in d: + v["mtPageId"] = ( + str.from_dict(d["mtPageId"]) + if hasattr(str, "from_dict") + else d["mtPageId"] + ) + if "mtPageType" in d: + v["mtPageType"] = ( + str.from_dict(d["mtPageType"]) + if hasattr(str, "from_dict") + else d["mtPageType"] + ) + if "mtPrevPage" in d: + v["mtPrevPage"] = ( + str.from_dict(d["mtPrevPage"]) + if hasattr(str, "from_dict") + else d["mtPrevPage"] + ) + if "mtRequestId" in d: + v["mtRequestId"] = ( + str.from_dict(d["mtRequestId"]) + if hasattr(str, "from_dict") + else d["mtRequestId"] + ) + if "mtTopic" in d: + v["mtTopic"] = ( + str.from_dict(d["mtTopic"]) + if hasattr(str, "from_dict") + else d["mtTopic"] + ) + if "currency" in d: + v["currency"] = ( + str.from_dict(d["currency"]) + if hasattr(str, "from_dict") + else d["currency"] + ) + if "exchangeRateToUSD" in d: + v["exchangeRateToUSD"] = ( + float.from_dict(d["exchangeRateToUSD"]) + if hasattr(float, "from_dict") + else d["exchangeRateToUSD"] + ) + if "commerceEvent_purchase_priceType" in d: + v["commerceEvent_purchase_priceType"] = ( + str.from_dict(d["commerceEvent_purchase_priceType"]) + if hasattr(str, "from_dict") + else d["commerceEvent_purchase_priceType"] + ) + if "commerceEvent_storeFrontId" in d: + v["commerceEvent_storeFrontId"] = ( + str.from_dict(d["commerceEvent_storeFrontId"]) + if hasattr(str, "from_dict") + else d["commerceEvent_storeFrontId"] + ) + if "commerceEvent_result_resultType" in d: + v["commerceEvent_result_resultType"] = ( + int.from_dict(d["commerceEvent_result_resultType"]) + if hasattr(int, "from_dict") + else d["commerceEvent_result_resultType"] + ) + if "commerceEvent_flowType" in d: + v["commerceEvent_flowType"] = ( + int.from_dict(d["commerceEvent_flowType"]) + if hasattr(int, "from_dict") + else d["commerceEvent_flowType"] + ) + if "commerceEvent_flowStep" in d: + v["commerceEvent_flowStep"] = ( + int.from_dict(d["commerceEvent_flowStep"]) + if hasattr(int, "from_dict") + else d["commerceEvent_flowStep"] + ) + if "dialogId" in d: + v["dialogId"] = ( + str.from_dict(d["dialogId"]) + if hasattr(str, "from_dict") + else d["dialogId"] + ) + if "message" in d: + v["message"] = ( + str.from_dict(d["message"]) + if hasattr(str, "from_dict") + else d["message"] + ) + if "messageCode" in d: + v["messageCode"] = ( + str.from_dict(d["messageCode"]) + if hasattr(str, "from_dict") + else d["messageCode"] + ) + if "options" in d: + v["options"] = [ + str.from_dict(p) if hasattr(str, "from_dict") else p + for p in d["options"] + ] + if "actionUrl" in d: + v["actionUrl"] = ( + str.from_dict(d["actionUrl"]) + if hasattr(str, "from_dict") + else d["actionUrl"] + ) + if "asnState" in d: + v["asnState"] = ( + int.from_dict(d["asnState"]) + if hasattr(int, "from_dict") + else d["asnState"] + ) + if "eventType" in d: + v["eventType"] = ( + str.from_dict(d["eventType"]) + if hasattr(str, "from_dict") + else d["eventType"] + ) + return StoreBuyproductResp._metrics(**v) + + def as_dict(self): + d = {} + if self.__itemIds is not None: + d["itemIds"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__itemIds + ] + if self.__price is not None: + d["price"] = ( + self.__price.as_dict() + if hasattr(self.__price, "as_dict") + else self.__price + ) + if self.__priceType is not None: + d["priceType"] = ( + self.__priceType.as_dict() + if hasattr(self.__priceType, "as_dict") + else self.__priceType + ) + if self.__productTypes is not None: + d["productTypes"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__productTypes + ] + if self.__mtApp is not None: + d["mtApp"] = ( + self.__mtApp.as_dict() + if hasattr(self.__mtApp, "as_dict") + else self.__mtApp + ) + if self.__mtClientId is not None: + d["mtClientId"] = ( + self.__mtClientId.as_dict() + if hasattr(self.__mtClientId, "as_dict") + else self.__mtClientId + ) + if self.__mtEventTime is not None: + d["mtEventTime"] = ( + self.__mtEventTime.as_dict() + if hasattr(self.__mtEventTime, "as_dict") + else self.__mtEventTime + ) + if self.__mtPageId is not None: + d["mtPageId"] = ( + self.__mtPageId.as_dict() + if hasattr(self.__mtPageId, "as_dict") + else self.__mtPageId + ) + if self.__mtPageType is not None: + d["mtPageType"] = ( + self.__mtPageType.as_dict() + if hasattr(self.__mtPageType, "as_dict") + else self.__mtPageType + ) + if self.__mtPrevPage is not None: + d["mtPrevPage"] = ( + self.__mtPrevPage.as_dict() + if hasattr(self.__mtPrevPage, "as_dict") + else self.__mtPrevPage + ) + if self.__mtRequestId is not None: + d["mtRequestId"] = ( + self.__mtRequestId.as_dict() + if hasattr(self.__mtRequestId, "as_dict") + else self.__mtRequestId + ) + if self.__mtTopic is not None: + d["mtTopic"] = ( + self.__mtTopic.as_dict() + if hasattr(self.__mtTopic, "as_dict") + else self.__mtTopic + ) + if self.__currency is not None: + d["currency"] = ( + self.__currency.as_dict() + if hasattr(self.__currency, "as_dict") + else self.__currency + ) + if self.__exchangeRateToUSD is not None: + d["exchangeRateToUSD"] = ( + self.__exchangeRateToUSD.as_dict() + if hasattr(self.__exchangeRateToUSD, "as_dict") + else self.__exchangeRateToUSD + ) + if self.__commerceEvent_purchase_priceType is not None: + d["commerceEvent_purchase_priceType"] = ( + self.__commerceEvent_purchase_priceType.as_dict() + if hasattr(self.__commerceEvent_purchase_priceType, "as_dict") + else self.__commerceEvent_purchase_priceType + ) + if self.__commerceEvent_storeFrontId is not None: + d["commerceEvent_storeFrontId"] = ( + self.__commerceEvent_storeFrontId.as_dict() + if hasattr(self.__commerceEvent_storeFrontId, "as_dict") + else self.__commerceEvent_storeFrontId + ) + if self.__commerceEvent_result_resultType is not None: + d["commerceEvent_result_resultType"] = ( + self.__commerceEvent_result_resultType.as_dict() + if hasattr(self.__commerceEvent_result_resultType, "as_dict") + else self.__commerceEvent_result_resultType + ) + if self.__commerceEvent_flowType is not None: + d["commerceEvent_flowType"] = ( + self.__commerceEvent_flowType.as_dict() + if hasattr(self.__commerceEvent_flowType, "as_dict") + else self.__commerceEvent_flowType + ) + if self.__commerceEvent_flowStep is not None: + d["commerceEvent_flowStep"] = ( + self.__commerceEvent_flowStep.as_dict() + if hasattr(self.__commerceEvent_flowStep, "as_dict") + else self.__commerceEvent_flowStep + ) + if self.__dialogId is not None: + d["dialogId"] = ( + self.__dialogId.as_dict() + if hasattr(self.__dialogId, "as_dict") + else self.__dialogId + ) + if self.__message is not None: + d["message"] = ( + self.__message.as_dict() + if hasattr(self.__message, "as_dict") + else self.__message + ) + if self.__messageCode is not None: + d["messageCode"] = ( + self.__messageCode.as_dict() + if hasattr(self.__messageCode, "as_dict") + else self.__messageCode + ) + if self.__options is not None: + d["options"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__options + ] + if self.__actionUrl is not None: + d["actionUrl"] = ( + self.__actionUrl.as_dict() + if hasattr(self.__actionUrl, "as_dict") + else self.__actionUrl + ) + if self.__asnState is not None: + d["asnState"] = ( + self.__asnState.as_dict() + if hasattr(self.__asnState, "as_dict") + else self.__asnState + ) + if self.__eventType is not None: + d["eventType"] = ( + self.__eventType.as_dict() + if hasattr(self.__eventType, "as_dict") + else self.__eventType + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__itemIds[:20] + if isinstance(self.__itemIds, bytes) + else self.__itemIds + ), + limitedRepr( + self.__price[:20] + if isinstance(self.__price, bytes) + else self.__price + ), + limitedRepr( + self.__priceType[:20] + if isinstance(self.__priceType, bytes) + else self.__priceType + ), + limitedRepr( + self.__productTypes[:20] + if isinstance(self.__productTypes, bytes) + else self.__productTypes + ), + limitedRepr( + self.__mtApp[:20] + if isinstance(self.__mtApp, bytes) + else self.__mtApp + ), + limitedRepr( + self.__mtClientId[:20] + if isinstance(self.__mtClientId, bytes) + else self.__mtClientId + ), + limitedRepr( + self.__mtEventTime[:20] + if isinstance(self.__mtEventTime, bytes) + else self.__mtEventTime + ), + limitedRepr( + self.__mtPageId[:20] + if isinstance(self.__mtPageId, bytes) + else self.__mtPageId + ), + limitedRepr( + self.__mtPageType[:20] + if isinstance(self.__mtPageType, bytes) + else self.__mtPageType + ), + limitedRepr( + self.__mtPrevPage[:20] + if isinstance(self.__mtPrevPage, bytes) + else self.__mtPrevPage + ), + limitedRepr( + self.__mtRequestId[:20] + if isinstance(self.__mtRequestId, bytes) + else self.__mtRequestId + ), + limitedRepr( + self.__mtTopic[:20] + if isinstance(self.__mtTopic, bytes) + else self.__mtTopic + ), + limitedRepr( + self.__currency[:20] + if isinstance(self.__currency, bytes) + else self.__currency + ), + limitedRepr( + self.__exchangeRateToUSD[:20] + if isinstance(self.__exchangeRateToUSD, bytes) + else self.__exchangeRateToUSD + ), + limitedRepr( + self.__commerceEvent_purchase_priceType[:20] + if isinstance(self.__commerceEvent_purchase_priceType, bytes) + else self.__commerceEvent_purchase_priceType + ), + limitedRepr( + self.__commerceEvent_storeFrontId[:20] + if isinstance(self.__commerceEvent_storeFrontId, bytes) + else self.__commerceEvent_storeFrontId + ), + limitedRepr( + self.__commerceEvent_result_resultType[:20] + if isinstance(self.__commerceEvent_result_resultType, bytes) + else self.__commerceEvent_result_resultType + ), + limitedRepr( + self.__commerceEvent_flowType[:20] + if isinstance(self.__commerceEvent_flowType, bytes) + else self.__commerceEvent_flowType + ), + limitedRepr( + self.__commerceEvent_flowStep[:20] + if isinstance(self.__commerceEvent_flowStep, bytes) + else self.__commerceEvent_flowStep + ), + limitedRepr( + self.__dialogId[:20] + if isinstance(self.__dialogId, bytes) + else self.__dialogId + ), + limitedRepr( + self.__message[:20] + if isinstance(self.__message, bytes) + else self.__message + ), + limitedRepr( + self.__messageCode[:20] + if isinstance(self.__messageCode, bytes) + else self.__messageCode + ), + limitedRepr( + self.__options[:20] + if isinstance(self.__options, bytes) + else self.__options + ), + limitedRepr( + self.__actionUrl[:20] + if isinstance(self.__actionUrl, bytes) + else self.__actionUrl + ), + limitedRepr( + self.__asnState[:20] + if isinstance(self.__asnState, bytes) + else self.__asnState + ), + limitedRepr( + self.__eventType[:20] + if isinstance(self.__eventType, bytes) + else self.__eventType + ), + ) + + _types_map = { + "pings": {"type": list, "subtype": float}, + "jingleDocType": {"type": str, "subtype": None}, + "jingleAction": {"type": str, "subtype": None}, + "status": {"type": int, "subtype": None}, + "dsPersonId": {"type": str, "subtype": None}, + "creditDisplay": {"type": str, "subtype": None}, + "creditBalance": {"type": str, "subtype": None}, + "freeSongBalance": {"type": str, "subtype": None}, + "creditDisplayInternal": {"type": str, "subtype": None}, + "authorized": {"type": bool, "subtype": None}, + "download_queue_item_count": {"type": int, "subtype": None}, + "songList": {"type": list, "subtype": _songList}, + "download_queue_info": {"type": _download_queue_info, "subtype": None}, + "metrics": {"type": _metrics, "subtype": None}, + "duAnonymousPings": {"type": list, "subtype": str}, + "subscriptionStatus": {"type": _subscriptionStatus, "subtype": None}, + "cancel_purchase_batch": {"type": bool, "subtype": None}, + "failureType": {"type": str, "subtype": None}, + "customerMessage": {"type": str, "subtype": None}, + "m_allowed": {"type": bool, "subtype": None}, + "dialog": {"type": _dialog, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "pings": { + "required": True, + }, + "jingleDocType": { + "required": False, + }, + "jingleAction": { + "required": False, + }, + "status": { + "required": False, + }, + "dsPersonId": { + "required": False, + }, + "creditDisplay": { + "required": False, + }, + "creditBalance": { + "required": False, + }, + "freeSongBalance": { + "required": False, + }, + "creditDisplayInternal": { + "required": False, + }, + "authorized": { + "required": False, + }, + "download_queue_item_count": { + "required": False, + }, + "songList": { + "required": False, + }, + "download_queue_info": { + "required": False, + }, + "metrics": { + "required": True, + }, + "duAnonymousPings": { + "required": False, + }, + "subscriptionStatus": { + "required": False, + }, + "cancel_purchase_batch": { + "required": False, + }, + "failureType": { + "required": False, + }, + "customerMessage": { + "required": False, + }, + "m_allowed": { + "required": False, + }, + "dialog": { + "required": False, + }, + } + + def __init__( + self, + pings: List[float] = None, + jingleDocType: str = None, + jingleAction: str = None, + status: int = None, + dsPersonId: str = None, + creditDisplay: str = None, + creditBalance: str = None, + freeSongBalance: str = None, + creditDisplayInternal: str = None, + authorized: bool = None, + download_queue_item_count: int = None, + songList: List[_songList] = None, + download_queue_info: _download_queue_info = None, + metrics: _metrics = None, + duAnonymousPings: List[str] = None, + subscriptionStatus: _subscriptionStatus = None, + cancel_purchase_batch: bool = None, + failureType: str = None, + customerMessage: str = None, + m_allowed: bool = None, + dialog: _dialog = None, + ): + pass + self.__pings = pings + self.__jingleDocType = jingleDocType + self.__jingleAction = jingleAction + self.__status = status + self.__dsPersonId = dsPersonId + self.__creditDisplay = creditDisplay + self.__creditBalance = creditBalance + self.__freeSongBalance = freeSongBalance + self.__creditDisplayInternal = creditDisplayInternal + self.__authorized = authorized + self.__download_queue_item_count = download_queue_item_count + self.__songList = songList + self.__download_queue_info = download_queue_info + self.__metrics = metrics + self.__duAnonymousPings = duAnonymousPings + self.__subscriptionStatus = subscriptionStatus + self.__cancel_purchase_batch = cancel_purchase_batch + self.__failureType = failureType + self.__customerMessage = customerMessage + self.__m_allowed = m_allowed + self.__dialog = dialog + + def _get_pings(self): + return self.__pings + + def _set_pings(self, value): + if not isinstance(value, list): + raise TypeError("pings must be list") + if not all(isinstance(i, float) for i in value): + raise TypeError("pings list values must be float") + + self.__pings = value + + pings = property(_get_pings, _set_pings) + + def _get_jingleDocType(self): + return self.__jingleDocType + + def _set_jingleDocType(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("jingleDocType must be str") + + self.__jingleDocType = value + + jingleDocType = property(_get_jingleDocType, _set_jingleDocType) + + def _get_jingleAction(self): + return self.__jingleAction + + def _set_jingleAction(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("jingleAction must be str") + + self.__jingleAction = value + + jingleAction = property(_get_jingleAction, _set_jingleAction) + + def _get_status(self): + return self.__status + + def _set_status(self, value): + if value is not None and not isinstance(value, int): + raise TypeError("status must be int") + + self.__status = value + + status = property(_get_status, _set_status) + + def _get_dsPersonId(self): + return self.__dsPersonId + + def _set_dsPersonId(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("dsPersonId must be str") + + self.__dsPersonId = value + + dsPersonId = property(_get_dsPersonId, _set_dsPersonId) + + def _get_creditDisplay(self): + return self.__creditDisplay + + def _set_creditDisplay(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("creditDisplay must be str") + + self.__creditDisplay = value + + creditDisplay = property(_get_creditDisplay, _set_creditDisplay) + + def _get_creditBalance(self): + return self.__creditBalance + + def _set_creditBalance(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("creditBalance must be str") + + self.__creditBalance = value + + creditBalance = property(_get_creditBalance, _set_creditBalance) + + def _get_freeSongBalance(self): + return self.__freeSongBalance + + def _set_freeSongBalance(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("freeSongBalance must be str") + + self.__freeSongBalance = value + + freeSongBalance = property(_get_freeSongBalance, _set_freeSongBalance) + + def _get_creditDisplayInternal(self): + return self.__creditDisplayInternal + + def _set_creditDisplayInternal(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("creditDisplayInternal must be str") + + self.__creditDisplayInternal = value + + creditDisplayInternal = property( + _get_creditDisplayInternal, _set_creditDisplayInternal + ) + + def _get_authorized(self): + return self.__authorized + + def _set_authorized(self, value): + if value is not None and not isinstance(value, bool): + raise TypeError("authorized must be bool") + + self.__authorized = value + + authorized = property(_get_authorized, _set_authorized) + + def _get_download_queue_item_count(self): + return self.__download_queue_item_count + + def _set_download_queue_item_count(self, value): + if value is not None and not isinstance(value, int): + raise TypeError("download_queue_item_count must be int") + + self.__download_queue_item_count = value + + download_queue_item_count = property( + _get_download_queue_item_count, _set_download_queue_item_count + ) + + def _get_songList(self): + return self.__songList + + def _set_songList(self, value): + if value is not None and not isinstance(value, list): + raise TypeError("songList must be list") + if value is not None and not all( + isinstance(i, StoreBuyproductResp._songList) for i in value + ): + raise TypeError( + "songList list values must be StoreBuyproductResp._songList" + ) + + self.__songList = value + + songList = property(_get_songList, _set_songList) + + def _get_download_queue_info(self): + return self.__download_queue_info + + def _set_download_queue_info(self, value): + if value is not None and not isinstance( + value, StoreBuyproductResp._download_queue_info + ): + raise TypeError( + "download_queue_info must be StoreBuyproductResp._download_queue_info" + ) + + self.__download_queue_info = value + + download_queue_info = property(_get_download_queue_info, _set_download_queue_info) + + def _get_metrics(self): + return self.__metrics + + def _set_metrics(self, value): + if not isinstance(value, StoreBuyproductResp._metrics): + raise TypeError("metrics must be StoreBuyproductResp._metrics") + + self.__metrics = value + + metrics = property(_get_metrics, _set_metrics) + + def _get_duAnonymousPings(self): + return self.__duAnonymousPings + + def _set_duAnonymousPings(self, value): + if value is not None and not isinstance(value, list): + raise TypeError("duAnonymousPings must be list") + if value is not None and not all(isinstance(i, str) for i in value): + raise TypeError("duAnonymousPings list values must be str") + + self.__duAnonymousPings = value + + duAnonymousPings = property(_get_duAnonymousPings, _set_duAnonymousPings) + + def _get_subscriptionStatus(self): + return self.__subscriptionStatus + + def _set_subscriptionStatus(self, value): + if value is not None and not isinstance( + value, StoreBuyproductResp._subscriptionStatus + ): + raise TypeError( + "subscriptionStatus must be StoreBuyproductResp._subscriptionStatus" + ) + + self.__subscriptionStatus = value + + subscriptionStatus = property(_get_subscriptionStatus, _set_subscriptionStatus) + + def _get_cancel_purchase_batch(self): + return self.__cancel_purchase_batch + + def _set_cancel_purchase_batch(self, value): + if value is not None and not isinstance(value, bool): + raise TypeError("cancel_purchase_batch must be bool") + + self.__cancel_purchase_batch = value + + cancel_purchase_batch = property( + _get_cancel_purchase_batch, _set_cancel_purchase_batch + ) + + def _get_failureType(self): + return self.__failureType + + def _set_failureType(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("failureType must be str") + + self.__failureType = value + + failureType = property(_get_failureType, _set_failureType) + + def _get_customerMessage(self): + return self.__customerMessage + + def _set_customerMessage(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("customerMessage must be str") + + self.__customerMessage = value + + customerMessage = property(_get_customerMessage, _set_customerMessage) + + def _get_m_allowed(self): + return self.__m_allowed + + def _set_m_allowed(self, value): + if value is not None and not isinstance(value, bool): + raise TypeError("m_allowed must be bool") + + self.__m_allowed = value + + m_allowed = property(_get_m_allowed, _set_m_allowed) + + def _get_dialog(self): + return self.__dialog + + def _set_dialog(self, value): + if value is not None and not isinstance(value, StoreBuyproductResp._dialog): + raise TypeError("dialog must be StoreBuyproductResp._dialog") + + self.__dialog = value + + dialog = property(_get_dialog, _set_dialog) + + @staticmethod + def from_dict(d): + v = {} + if "pings" in d: + v["pings"] = [ + float.from_dict(p) if hasattr(float, "from_dict") else p + for p in d["pings"] + ] + if "jingleDocType" in d: + v["jingleDocType"] = ( + str.from_dict(d["jingleDocType"]) + if hasattr(str, "from_dict") + else d["jingleDocType"] + ) + if "jingleAction" in d: + v["jingleAction"] = ( + str.from_dict(d["jingleAction"]) + if hasattr(str, "from_dict") + else d["jingleAction"] + ) + if "status" in d: + v["status"] = ( + int.from_dict(d["status"]) if hasattr(int, "from_dict") else d["status"] + ) + if "dsPersonId" in d: + v["dsPersonId"] = ( + str.from_dict(d["dsPersonId"]) + if hasattr(str, "from_dict") + else d["dsPersonId"] + ) + if "creditDisplay" in d: + v["creditDisplay"] = ( + str.from_dict(d["creditDisplay"]) + if hasattr(str, "from_dict") + else d["creditDisplay"] + ) + if "creditBalance" in d: + v["creditBalance"] = ( + str.from_dict(d["creditBalance"]) + if hasattr(str, "from_dict") + else d["creditBalance"] + ) + if "freeSongBalance" in d: + v["freeSongBalance"] = ( + str.from_dict(d["freeSongBalance"]) + if hasattr(str, "from_dict") + else d["freeSongBalance"] + ) + if "creditDisplayInternal" in d: + v["creditDisplayInternal"] = ( + str.from_dict(d["creditDisplayInternal"]) + if hasattr(str, "from_dict") + else d["creditDisplayInternal"] + ) + if "authorized" in d: + v["authorized"] = ( + bool.from_dict(d["authorized"]) + if hasattr(bool, "from_dict") + else d["authorized"] + ) + if "download-queue-item-count" in d: + v["download_queue_item_count"] = ( + int.from_dict(d["download-queue-item-count"]) + if hasattr(int, "from_dict") + else d["download-queue-item-count"] + ) + if "songList" in d: + v["songList"] = [ + StoreBuyproductResp._songList.from_dict(p) + if hasattr(StoreBuyproductResp._songList, "from_dict") + else p + for p in d["songList"] + ] + if "download-queue-info" in d: + v["download_queue_info"] = ( + StoreBuyproductResp._download_queue_info.from_dict( + d["download-queue-info"] + ) + if hasattr(StoreBuyproductResp._download_queue_info, "from_dict") + else d["download-queue-info"] + ) + if "metrics" in d: + v["metrics"] = ( + StoreBuyproductResp._metrics.from_dict(d["metrics"]) + if hasattr(StoreBuyproductResp._metrics, "from_dict") + else d["metrics"] + ) + if "duAnonymousPings" in d: + v["duAnonymousPings"] = [ + str.from_dict(p) if hasattr(str, "from_dict") else p + for p in d["duAnonymousPings"] + ] + if "subscriptionStatus" in d: + v["subscriptionStatus"] = ( + StoreBuyproductResp._subscriptionStatus.from_dict( + d["subscriptionStatus"] + ) + if hasattr(StoreBuyproductResp._subscriptionStatus, "from_dict") + else d["subscriptionStatus"] + ) + if "cancel-purchase-batch" in d: + v["cancel_purchase_batch"] = ( + bool.from_dict(d["cancel-purchase-batch"]) + if hasattr(bool, "from_dict") + else d["cancel-purchase-batch"] + ) + if "failureType" in d: + v["failureType"] = ( + str.from_dict(d["failureType"]) + if hasattr(str, "from_dict") + else d["failureType"] + ) + if "customerMessage" in d: + v["customerMessage"] = ( + str.from_dict(d["customerMessage"]) + if hasattr(str, "from_dict") + else d["customerMessage"] + ) + if "m-allowed" in d: + v["m_allowed"] = ( + bool.from_dict(d["m-allowed"]) + if hasattr(bool, "from_dict") + else d["m-allowed"] + ) + if "dialog" in d: + v["dialog"] = ( + StoreBuyproductResp._dialog.from_dict(d["dialog"]) + if hasattr(StoreBuyproductResp._dialog, "from_dict") + else d["dialog"] + ) + return StoreBuyproductResp(**v) + + def as_dict(self): + d = {} + if self.__pings is not None: + d["pings"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__pings + ] + if self.__jingleDocType is not None: + d["jingleDocType"] = ( + self.__jingleDocType.as_dict() + if hasattr(self.__jingleDocType, "as_dict") + else self.__jingleDocType + ) + if self.__jingleAction is not None: + d["jingleAction"] = ( + self.__jingleAction.as_dict() + if hasattr(self.__jingleAction, "as_dict") + else self.__jingleAction + ) + if self.__status is not None: + d["status"] = ( + self.__status.as_dict() + if hasattr(self.__status, "as_dict") + else self.__status + ) + if self.__dsPersonId is not None: + d["dsPersonId"] = ( + self.__dsPersonId.as_dict() + if hasattr(self.__dsPersonId, "as_dict") + else self.__dsPersonId + ) + if self.__creditDisplay is not None: + d["creditDisplay"] = ( + self.__creditDisplay.as_dict() + if hasattr(self.__creditDisplay, "as_dict") + else self.__creditDisplay + ) + if self.__creditBalance is not None: + d["creditBalance"] = ( + self.__creditBalance.as_dict() + if hasattr(self.__creditBalance, "as_dict") + else self.__creditBalance + ) + if self.__freeSongBalance is not None: + d["freeSongBalance"] = ( + self.__freeSongBalance.as_dict() + if hasattr(self.__freeSongBalance, "as_dict") + else self.__freeSongBalance + ) + if self.__creditDisplayInternal is not None: + d["creditDisplayInternal"] = ( + self.__creditDisplayInternal.as_dict() + if hasattr(self.__creditDisplayInternal, "as_dict") + else self.__creditDisplayInternal + ) + if self.__authorized is not None: + d["authorized"] = ( + self.__authorized.as_dict() + if hasattr(self.__authorized, "as_dict") + else self.__authorized + ) + if self.__download_queue_item_count is not None: + d["download-queue-item-count"] = ( + self.__download_queue_item_count.as_dict() + if hasattr(self.__download_queue_item_count, "as_dict") + else self.__download_queue_item_count + ) + if self.__songList is not None: + d["songList"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__songList + ] + if self.__download_queue_info is not None: + d["download-queue-info"] = ( + self.__download_queue_info.as_dict() + if hasattr(self.__download_queue_info, "as_dict") + else self.__download_queue_info + ) + if self.__metrics is not None: + d["metrics"] = ( + self.__metrics.as_dict() + if hasattr(self.__metrics, "as_dict") + else self.__metrics + ) + if self.__duAnonymousPings is not None: + d["duAnonymousPings"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__duAnonymousPings + ] + if self.__subscriptionStatus is not None: + d["subscriptionStatus"] = ( + self.__subscriptionStatus.as_dict() + if hasattr(self.__subscriptionStatus, "as_dict") + else self.__subscriptionStatus + ) + if self.__cancel_purchase_batch is not None: + d["cancel-purchase-batch"] = ( + self.__cancel_purchase_batch.as_dict() + if hasattr(self.__cancel_purchase_batch, "as_dict") + else self.__cancel_purchase_batch + ) + if self.__failureType is not None: + d["failureType"] = ( + self.__failureType.as_dict() + if hasattr(self.__failureType, "as_dict") + else self.__failureType + ) + if self.__customerMessage is not None: + d["customerMessage"] = ( + self.__customerMessage.as_dict() + if hasattr(self.__customerMessage, "as_dict") + else self.__customerMessage + ) + if self.__m_allowed is not None: + d["m-allowed"] = ( + self.__m_allowed.as_dict() + if hasattr(self.__m_allowed, "as_dict") + else self.__m_allowed + ) + if self.__dialog is not None: + d["dialog"] = ( + self.__dialog.as_dict() + if hasattr(self.__dialog, "as_dict") + else self.__dialog + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__pings[:20] if isinstance(self.__pings, bytes) else self.__pings + ), + limitedRepr( + self.__jingleDocType[:20] + if isinstance(self.__jingleDocType, bytes) + else self.__jingleDocType + ), + limitedRepr( + self.__jingleAction[:20] + if isinstance(self.__jingleAction, bytes) + else self.__jingleAction + ), + limitedRepr( + self.__status[:20] + if isinstance(self.__status, bytes) + else self.__status + ), + limitedRepr( + self.__dsPersonId[:20] + if isinstance(self.__dsPersonId, bytes) + else self.__dsPersonId + ), + limitedRepr( + self.__creditDisplay[:20] + if isinstance(self.__creditDisplay, bytes) + else self.__creditDisplay + ), + limitedRepr( + self.__creditBalance[:20] + if isinstance(self.__creditBalance, bytes) + else self.__creditBalance + ), + limitedRepr( + self.__freeSongBalance[:20] + if isinstance(self.__freeSongBalance, bytes) + else self.__freeSongBalance + ), + limitedRepr( + self.__creditDisplayInternal[:20] + if isinstance(self.__creditDisplayInternal, bytes) + else self.__creditDisplayInternal + ), + limitedRepr( + self.__authorized[:20] + if isinstance(self.__authorized, bytes) + else self.__authorized + ), + limitedRepr( + self.__download_queue_item_count[:20] + if isinstance(self.__download_queue_item_count, bytes) + else self.__download_queue_item_count + ), + limitedRepr( + self.__songList[:20] + if isinstance(self.__songList, bytes) + else self.__songList + ), + limitedRepr( + self.__download_queue_info[:20] + if isinstance(self.__download_queue_info, bytes) + else self.__download_queue_info + ), + limitedRepr( + self.__metrics[:20] + if isinstance(self.__metrics, bytes) + else self.__metrics + ), + limitedRepr( + self.__duAnonymousPings[:20] + if isinstance(self.__duAnonymousPings, bytes) + else self.__duAnonymousPings + ), + limitedRepr( + self.__subscriptionStatus[:20] + if isinstance(self.__subscriptionStatus, bytes) + else self.__subscriptionStatus + ), + limitedRepr( + self.__cancel_purchase_batch[:20] + if isinstance(self.__cancel_purchase_batch, bytes) + else self.__cancel_purchase_batch + ), + limitedRepr( + self.__failureType[:20] + if isinstance(self.__failureType, bytes) + else self.__failureType + ), + limitedRepr( + self.__customerMessage[:20] + if isinstance(self.__customerMessage, bytes) + else self.__customerMessage + ), + limitedRepr( + self.__m_allowed[:20] + if isinstance(self.__m_allowed, bytes) + else self.__m_allowed + ), + limitedRepr( + self.__dialog[:20] + if isinstance(self.__dialog, bytes) + else self.__dialog + ), + ) diff --git a/src_mac/ipatool-py/reqs/schemas/store_download_req.py b/src_mac/ipatool-py/reqs/schemas/store_download_req.py new file mode 100755 index 0000000..04d5a03 --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/store_download_req.py @@ -0,0 +1,160 @@ +from reprlib import repr as limitedRepr + + +class StoreDownloadReq: + + _types_map = { + "creditDisplay": {"type": str, "subtype": None}, + "guid": {"type": str, "subtype": None}, + "salableAdamId": {"type": str, "subtype": None}, + "appExtVrsId": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "creditDisplay": { + "required": True, + }, + "guid": { + "required": True, + }, + "salableAdamId": { + "required": True, + }, + "appExtVrsId": { + "required": False, + }, + } + + def __init__( + self, + creditDisplay: str = None, + guid: str = None, + salableAdamId: str = None, + appExtVrsId: str = None, + ): + pass + self.__creditDisplay = creditDisplay + self.__guid = guid + self.__salableAdamId = salableAdamId + self.__appExtVrsId = appExtVrsId + + def _get_creditDisplay(self): + return self.__creditDisplay + + def _set_creditDisplay(self, value): + if not isinstance(value, str): + raise TypeError("creditDisplay must be str") + + self.__creditDisplay = value + + creditDisplay = property(_get_creditDisplay, _set_creditDisplay) + + def _get_guid(self): + return self.__guid + + def _set_guid(self, value): + if not isinstance(value, str): + raise TypeError("guid must be str") + + self.__guid = value + + guid = property(_get_guid, _set_guid) + + def _get_salableAdamId(self): + return self.__salableAdamId + + def _set_salableAdamId(self, value): + if not isinstance(value, str): + raise TypeError("salableAdamId must be str") + + self.__salableAdamId = value + + salableAdamId = property(_get_salableAdamId, _set_salableAdamId) + + def _get_appExtVrsId(self): + return self.__appExtVrsId + + def _set_appExtVrsId(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("appExtVrsId must be str") + + self.__appExtVrsId = value + + appExtVrsId = property(_get_appExtVrsId, _set_appExtVrsId) + + @staticmethod + def from_dict(d): + v = {} + if "creditDisplay" in d: + v["creditDisplay"] = ( + str.from_dict(d["creditDisplay"]) + if hasattr(str, "from_dict") + else d["creditDisplay"] + ) + if "guid" in d: + v["guid"] = ( + str.from_dict(d["guid"]) if hasattr(str, "from_dict") else d["guid"] + ) + if "salableAdamId" in d: + v["salableAdamId"] = ( + str.from_dict(d["salableAdamId"]) + if hasattr(str, "from_dict") + else d["salableAdamId"] + ) + if "appExtVrsId" in d: + v["appExtVrsId"] = ( + str.from_dict(d["appExtVrsId"]) + if hasattr(str, "from_dict") + else d["appExtVrsId"] + ) + return StoreDownloadReq(**v) + + def as_dict(self): + d = {} + if self.__creditDisplay is not None: + d["creditDisplay"] = ( + self.__creditDisplay.as_dict() + if hasattr(self.__creditDisplay, "as_dict") + else self.__creditDisplay + ) + if self.__guid is not None: + d["guid"] = ( + self.__guid.as_dict() + if hasattr(self.__guid, "as_dict") + else self.__guid + ) + if self.__salableAdamId is not None: + d["salableAdamId"] = ( + self.__salableAdamId.as_dict() + if hasattr(self.__salableAdamId, "as_dict") + else self.__salableAdamId + ) + if self.__appExtVrsId is not None: + d["appExtVrsId"] = ( + self.__appExtVrsId.as_dict() + if hasattr(self.__appExtVrsId, "as_dict") + else self.__appExtVrsId + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__creditDisplay[:20] + if isinstance(self.__creditDisplay, bytes) + else self.__creditDisplay + ), + limitedRepr( + self.__guid[:20] if isinstance(self.__guid, bytes) else self.__guid + ), + limitedRepr( + self.__salableAdamId[:20] + if isinstance(self.__salableAdamId, bytes) + else self.__salableAdamId + ), + limitedRepr( + self.__appExtVrsId[:20] + if isinstance(self.__appExtVrsId, bytes) + else self.__appExtVrsId + ), + ) diff --git a/src_mac/ipatool-py/reqs/schemas/store_download_resp.py b/src_mac/ipatool-py/reqs/schemas/store_download_resp.py new file mode 100755 index 0000000..87baac4 --- /dev/null +++ b/src_mac/ipatool-py/reqs/schemas/store_download_resp.py @@ -0,0 +1,3910 @@ +from reprlib import repr as limitedRepr + + +from typing import List + + +class StoreDownloadResp: + class _songList: + class _chunks: + + _types_map = { + "chunkSize": {"type": int, "subtype": None}, + "hashes": {"type": list, "subtype": str}, + } + _formats_map = {} + _validations_map = { + "chunkSize": { + "required": True, + }, + "hashes": { + "required": True, + }, + } + + def __init__(self, chunkSize: int = None, hashes: List[str] = None): + pass + self.__chunkSize = chunkSize + self.__hashes = hashes + + def _get_chunkSize(self): + return self.__chunkSize + + def _set_chunkSize(self, value): + if not isinstance(value, int): + raise TypeError("chunkSize must be int") + + self.__chunkSize = value + + chunkSize = property(_get_chunkSize, _set_chunkSize) + + def _get_hashes(self): + return self.__hashes + + def _set_hashes(self, value): + if not isinstance(value, list): + raise TypeError("hashes must be list") + if not all(isinstance(i, str) for i in value): + raise TypeError("hashes list values must be str") + + self.__hashes = value + + hashes = property(_get_hashes, _set_hashes) + + @staticmethod + def from_dict(d): + v = {} + if "chunkSize" in d: + v["chunkSize"] = ( + int.from_dict(d["chunkSize"]) + if hasattr(int, "from_dict") + else d["chunkSize"] + ) + if "hashes" in d: + v["hashes"] = [ + str.from_dict(p) if hasattr(str, "from_dict") else p + for p in d["hashes"] + ] + return StoreDownloadResp._songList._chunks(**v) + + def as_dict(self): + d = {} + if self.__chunkSize is not None: + d["chunkSize"] = ( + self.__chunkSize.as_dict() + if hasattr(self.__chunkSize, "as_dict") + else self.__chunkSize + ) + if self.__hashes is not None: + d["hashes"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__hashes + ] + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__chunkSize[:20] + if isinstance(self.__chunkSize, bytes) + else self.__chunkSize + ), + limitedRepr( + self.__hashes[:20] + if isinstance(self.__hashes, bytes) + else self.__hashes + ), + ) + + class _artwork_urls: + class _default: + + _types_map = { + "url": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "url": { + "required": True, + }, + } + + def __init__(self, url: str = None): + pass + self.__url = url + + def _get_url(self): + return self.__url + + def _set_url(self, value): + if not isinstance(value, str): + raise TypeError("url must be str") + + self.__url = value + + url = property(_get_url, _set_url) + + @staticmethod + def from_dict(d): + v = {} + if "url" in d: + v["url"] = ( + str.from_dict(d["url"]) + if hasattr(str, "from_dict") + else d["url"] + ) + return StoreDownloadResp._songList._artwork_urls._default(**v) + + def as_dict(self): + d = {} + if self.__url is not None: + d["url"] = ( + self.__url.as_dict() + if hasattr(self.__url, "as_dict") + else self.__url + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__url[:20] + if isinstance(self.__url, bytes) + else self.__url + ) + ) + + _types_map = { + "image_type": {"type": str, "subtype": None}, + "default": {"type": _default, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "image_type": { + "required": True, + }, + "default": { + "required": True, + }, + } + + def __init__(self, image_type: str = None, default: _default = None): + pass + self.__image_type = image_type + self.__default = default + + def _get_image_type(self): + return self.__image_type + + def _set_image_type(self, value): + if not isinstance(value, str): + raise TypeError("image_type must be str") + + self.__image_type = value + + image_type = property(_get_image_type, _set_image_type) + + def _get_default(self): + return self.__default + + def _set_default(self, value): + if not isinstance( + value, StoreDownloadResp._songList._artwork_urls._default + ): + raise TypeError( + "default must be StoreDownloadResp._songList._artwork_urls._default" + ) + + self.__default = value + + default = property(_get_default, _set_default) + + @staticmethod + def from_dict(d): + v = {} + if "image-type" in d: + v["image_type"] = ( + str.from_dict(d["image-type"]) + if hasattr(str, "from_dict") + else d["image-type"] + ) + if "default" in d: + v["default"] = ( + StoreDownloadResp._songList._artwork_urls._default.from_dict( + d["default"] + ) + if hasattr( + StoreDownloadResp._songList._artwork_urls._default, + "from_dict", + ) + else d["default"] + ) + return StoreDownloadResp._songList._artwork_urls(**v) + + def as_dict(self): + d = {} + if self.__image_type is not None: + d["image-type"] = ( + self.__image_type.as_dict() + if hasattr(self.__image_type, "as_dict") + else self.__image_type + ) + if self.__default is not None: + d["default"] = ( + self.__default.as_dict() + if hasattr(self.__default, "as_dict") + else self.__default + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__image_type[:20] + if isinstance(self.__image_type, bytes) + else self.__image_type + ), + limitedRepr( + self.__default[:20] + if isinstance(self.__default, bytes) + else self.__default + ), + ) + + class _sinfs: + + _types_map = { + "id": {"type": int, "subtype": None}, + "sinf": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "id": { + "required": True, + }, + "sinf": { + "required": True, + }, + } + + def __init__(self, id: int = None, sinf: str = None): + pass + self.__id = id + self.__sinf = sinf + + def _get_id(self): + return self.__id + + def _set_id(self, value): + if not isinstance(value, int): + raise TypeError("id must be int") + + self.__id = value + + id = property(_get_id, _set_id) + + def _get_sinf(self): + return self.__sinf + + def _set_sinf(self, value): + if not isinstance(value, str): + raise TypeError("sinf must be str") + + self.__sinf = value + + sinf = property(_get_sinf, _set_sinf) + + @staticmethod + def from_dict(d): + v = {} + if "id" in d: + v["id"] = ( + int.from_dict(d["id"]) if hasattr(int, "from_dict") else d["id"] + ) + if "sinf" in d: + v["sinf"] = ( + str.from_dict(d["sinf"]) + if hasattr(str, "from_dict") + else d["sinf"] + ) + return StoreDownloadResp._songList._sinfs(**v) + + def as_dict(self): + d = {} + if self.__id is not None: + d["id"] = ( + self.__id.as_dict() + if hasattr(self.__id, "as_dict") + else self.__id + ) + if self.__sinf is not None: + d["sinf"] = ( + self.__sinf.as_dict() + if hasattr(self.__sinf, "as_dict") + else self.__sinf + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__id[:20] if isinstance(self.__id, bytes) else self.__id + ), + limitedRepr( + self.__sinf[:20] + if isinstance(self.__sinf, bytes) + else self.__sinf + ), + ) + + class _asset_info: + + _types_map = { + "file_size": {"type": int, "subtype": None}, + "flavor": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "file_size": { + "required": True, + }, + "flavor": { + "required": True, + }, + } + + def __init__(self, file_size: int = None, flavor: str = None): + pass + self.__file_size = file_size + self.__flavor = flavor + + def _get_file_size(self): + return self.__file_size + + def _set_file_size(self, value): + if not isinstance(value, int): + raise TypeError("file_size must be int") + + self.__file_size = value + + file_size = property(_get_file_size, _set_file_size) + + def _get_flavor(self): + return self.__flavor + + def _set_flavor(self, value): + if not isinstance(value, str): + raise TypeError("flavor must be str") + + self.__flavor = value + + flavor = property(_get_flavor, _set_flavor) + + @staticmethod + def from_dict(d): + v = {} + if "file-size" in d: + v["file_size"] = ( + int.from_dict(d["file-size"]) + if hasattr(int, "from_dict") + else d["file-size"] + ) + if "flavor" in d: + v["flavor"] = ( + str.from_dict(d["flavor"]) + if hasattr(str, "from_dict") + else d["flavor"] + ) + return StoreDownloadResp._songList._asset_info(**v) + + def as_dict(self): + d = {} + if self.__file_size is not None: + d["file-size"] = ( + self.__file_size.as_dict() + if hasattr(self.__file_size, "as_dict") + else self.__file_size + ) + if self.__flavor is not None: + d["flavor"] = ( + self.__flavor.as_dict() + if hasattr(self.__flavor, "as_dict") + else self.__flavor + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__file_size[:20] + if isinstance(self.__file_size, bytes) + else self.__file_size + ), + limitedRepr( + self.__flavor[:20] + if isinstance(self.__flavor, bytes) + else self.__flavor + ), + ) + + class _metadata: + class _MacUIRequiredDeviceCapabilities: + + _types_map = { + "arm64": {"type": bool, "subtype": None}, + "gamekit": {"type": bool, "subtype": None}, + "metal": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "arm64": { + "required": True, + }, + "gamekit": { + "required": True, + }, + "metal": { + "required": True, + }, + } + + def __init__( + self, arm64: bool = None, gamekit: bool = None, metal: bool = None + ): + pass + self.__arm64 = arm64 + self.__gamekit = gamekit + self.__metal = metal + + def _get_arm64(self): + return self.__arm64 + + def _set_arm64(self, value): + if not isinstance(value, bool): + raise TypeError("arm64 must be bool") + + self.__arm64 = value + + arm64 = property(_get_arm64, _set_arm64) + + def _get_gamekit(self): + return self.__gamekit + + def _set_gamekit(self, value): + if not isinstance(value, bool): + raise TypeError("gamekit must be bool") + + self.__gamekit = value + + gamekit = property(_get_gamekit, _set_gamekit) + + def _get_metal(self): + return self.__metal + + def _set_metal(self, value): + if not isinstance(value, bool): + raise TypeError("metal must be bool") + + self.__metal = value + + metal = property(_get_metal, _set_metal) + + @staticmethod + def from_dict(d): + v = {} + if "arm64" in d: + v["arm64"] = ( + bool.from_dict(d["arm64"]) + if hasattr(bool, "from_dict") + else d["arm64"] + ) + if "gamekit" in d: + v["gamekit"] = ( + bool.from_dict(d["gamekit"]) + if hasattr(bool, "from_dict") + else d["gamekit"] + ) + if "metal" in d: + v["metal"] = ( + bool.from_dict(d["metal"]) + if hasattr(bool, "from_dict") + else d["metal"] + ) + return StoreDownloadResp._songList._metadata._MacUIRequiredDeviceCapabilities( + **v + ) + + def as_dict(self): + d = {} + if self.__arm64 is not None: + d["arm64"] = ( + self.__arm64.as_dict() + if hasattr(self.__arm64, "as_dict") + else self.__arm64 + ) + if self.__gamekit is not None: + d["gamekit"] = ( + self.__gamekit.as_dict() + if hasattr(self.__gamekit, "as_dict") + else self.__gamekit + ) + if self.__metal is not None: + d["metal"] = ( + self.__metal.as_dict() + if hasattr(self.__metal, "as_dict") + else self.__metal + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__arm64[:20] + if isinstance(self.__arm64, bytes) + else self.__arm64 + ), + limitedRepr( + self.__gamekit[:20] + if isinstance(self.__gamekit, bytes) + else self.__gamekit + ), + limitedRepr( + self.__metal[:20] + if isinstance(self.__metal, bytes) + else self.__metal + ), + ) + + class _UIRequiredDeviceCapabilities: + + _types_map = { + "arm64": {"type": bool, "subtype": None}, + "gamekit": {"type": bool, "subtype": None}, + "metal": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "arm64": { + "required": True, + }, + "gamekit": { + "required": True, + }, + "metal": { + "required": True, + }, + } + + def __init__( + self, arm64: bool = None, gamekit: bool = None, metal: bool = None + ): + pass + self.__arm64 = arm64 + self.__gamekit = gamekit + self.__metal = metal + + def _get_arm64(self): + return self.__arm64 + + def _set_arm64(self, value): + if not isinstance(value, bool): + raise TypeError("arm64 must be bool") + + self.__arm64 = value + + arm64 = property(_get_arm64, _set_arm64) + + def _get_gamekit(self): + return self.__gamekit + + def _set_gamekit(self, value): + if not isinstance(value, bool): + raise TypeError("gamekit must be bool") + + self.__gamekit = value + + gamekit = property(_get_gamekit, _set_gamekit) + + def _get_metal(self): + return self.__metal + + def _set_metal(self, value): + if not isinstance(value, bool): + raise TypeError("metal must be bool") + + self.__metal = value + + metal = property(_get_metal, _set_metal) + + @staticmethod + def from_dict(d): + v = {} + if "arm64" in d: + v["arm64"] = ( + bool.from_dict(d["arm64"]) + if hasattr(bool, "from_dict") + else d["arm64"] + ) + if "gamekit" in d: + v["gamekit"] = ( + bool.from_dict(d["gamekit"]) + if hasattr(bool, "from_dict") + else d["gamekit"] + ) + if "metal" in d: + v["metal"] = ( + bool.from_dict(d["metal"]) + if hasattr(bool, "from_dict") + else d["metal"] + ) + return StoreDownloadResp._songList._metadata._UIRequiredDeviceCapabilities( + **v + ) + + def as_dict(self): + d = {} + if self.__arm64 is not None: + d["arm64"] = ( + self.__arm64.as_dict() + if hasattr(self.__arm64, "as_dict") + else self.__arm64 + ) + if self.__gamekit is not None: + d["gamekit"] = ( + self.__gamekit.as_dict() + if hasattr(self.__gamekit, "as_dict") + else self.__gamekit + ) + if self.__metal is not None: + d["metal"] = ( + self.__metal.as_dict() + if hasattr(self.__metal, "as_dict") + else self.__metal + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__arm64[:20] + if isinstance(self.__arm64, bytes) + else self.__arm64 + ), + limitedRepr( + self.__gamekit[:20] + if isinstance(self.__gamekit, bytes) + else self.__gamekit + ), + limitedRepr( + self.__metal[:20] + if isinstance(self.__metal, bytes) + else self.__metal + ), + ) + + class _subgenres: + + _types_map = { + "genre": {"type": str, "subtype": None}, + "genreId": {"type": int, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "genre": { + "required": True, + }, + "genreId": { + "required": True, + }, + } + + def __init__(self, genre: str = None, genreId: int = None): + pass + self.__genre = genre + self.__genreId = genreId + + def _get_genre(self): + return self.__genre + + def _set_genre(self, value): + if not isinstance(value, str): + raise TypeError("genre must be str") + + self.__genre = value + + genre = property(_get_genre, _set_genre) + + def _get_genreId(self): + return self.__genreId + + def _set_genreId(self, value): + if not isinstance(value, int): + raise TypeError("genreId must be int") + + self.__genreId = value + + genreId = property(_get_genreId, _set_genreId) + + @staticmethod + def from_dict(d): + v = {} + if "genre" in d: + v["genre"] = ( + str.from_dict(d["genre"]) + if hasattr(str, "from_dict") + else d["genre"] + ) + if "genreId" in d: + v["genreId"] = ( + int.from_dict(d["genreId"]) + if hasattr(int, "from_dict") + else d["genreId"] + ) + return StoreDownloadResp._songList._metadata._subgenres(**v) + + def as_dict(self): + d = {} + if self.__genre is not None: + d["genre"] = ( + self.__genre.as_dict() + if hasattr(self.__genre, "as_dict") + else self.__genre + ) + if self.__genreId is not None: + d["genreId"] = ( + self.__genreId.as_dict() + if hasattr(self.__genreId, "as_dict") + else self.__genreId + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__genre[:20] + if isinstance(self.__genre, bytes) + else self.__genre + ), + limitedRepr( + self.__genreId[:20] + if isinstance(self.__genreId, bytes) + else self.__genreId + ), + ) + + class _rating: + + _types_map = { + "content": {"type": str, "subtype": None}, + "label": {"type": str, "subtype": None}, + "rank": {"type": int, "subtype": None}, + "system": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "content": { + "required": True, + }, + "label": { + "required": True, + }, + "rank": { + "required": True, + }, + "system": { + "required": True, + }, + } + + def __init__( + self, + content: str = None, + label: str = None, + rank: int = None, + system: str = None, + ): + pass + self.__content = content + self.__label = label + self.__rank = rank + self.__system = system + + def _get_content(self): + return self.__content + + def _set_content(self, value): + if not isinstance(value, str): + raise TypeError("content must be str") + + self.__content = value + + content = property(_get_content, _set_content) + + def _get_label(self): + return self.__label + + def _set_label(self, value): + if not isinstance(value, str): + raise TypeError("label must be str") + + self.__label = value + + label = property(_get_label, _set_label) + + def _get_rank(self): + return self.__rank + + def _set_rank(self, value): + if not isinstance(value, int): + raise TypeError("rank must be int") + + self.__rank = value + + rank = property(_get_rank, _set_rank) + + def _get_system(self): + return self.__system + + def _set_system(self, value): + if not isinstance(value, str): + raise TypeError("system must be str") + + self.__system = value + + system = property(_get_system, _set_system) + + @staticmethod + def from_dict(d): + v = {} + if "content" in d: + v["content"] = ( + str.from_dict(d["content"]) + if hasattr(str, "from_dict") + else d["content"] + ) + if "label" in d: + v["label"] = ( + str.from_dict(d["label"]) + if hasattr(str, "from_dict") + else d["label"] + ) + if "rank" in d: + v["rank"] = ( + int.from_dict(d["rank"]) + if hasattr(int, "from_dict") + else d["rank"] + ) + if "system" in d: + v["system"] = ( + str.from_dict(d["system"]) + if hasattr(str, "from_dict") + else d["system"] + ) + return StoreDownloadResp._songList._metadata._rating(**v) + + def as_dict(self): + d = {} + if self.__content is not None: + d["content"] = ( + self.__content.as_dict() + if hasattr(self.__content, "as_dict") + else self.__content + ) + if self.__label is not None: + d["label"] = ( + self.__label.as_dict() + if hasattr(self.__label, "as_dict") + else self.__label + ) + if self.__rank is not None: + d["rank"] = ( + self.__rank.as_dict() + if hasattr(self.__rank, "as_dict") + else self.__rank + ) + if self.__system is not None: + d["system"] = ( + self.__system.as_dict() + if hasattr(self.__system, "as_dict") + else self.__system + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__content[:20] + if isinstance(self.__content, bytes) + else self.__content + ), + limitedRepr( + self.__label[:20] + if isinstance(self.__label, bytes) + else self.__label + ), + limitedRepr( + self.__rank[:20] + if isinstance(self.__rank, bytes) + else self.__rank + ), + limitedRepr( + self.__system[:20] + if isinstance(self.__system, bytes) + else self.__system + ), + ) + + _types_map = { + "MacUIRequiredDeviceCapabilities": { + "type": _MacUIRequiredDeviceCapabilities, + "subtype": None, + }, + "UIRequiredDeviceCapabilities": { + "type": _UIRequiredDeviceCapabilities, + "subtype": None, + }, + "artistId": {"type": int, "subtype": None}, + "artistName": {"type": str, "subtype": None}, + "bundleDisplayName": {"type": str, "subtype": None}, + "bundleShortVersionString": {"type": str, "subtype": None}, + "bundleVersion": {"type": str, "subtype": None}, + "copyright": {"type": str, "subtype": None}, + "fileExtension": {"type": str, "subtype": None}, + "gameCenterEnabled": {"type": bool, "subtype": None}, + "gameCenterEverEnabled": {"type": bool, "subtype": None}, + "genre": {"type": str, "subtype": None}, + "genreId": {"type": int, "subtype": None}, + "itemId": {"type": int, "subtype": None}, + "itemName": {"type": str, "subtype": None}, + "kind": {"type": str, "subtype": None}, + "playlistName": {"type": str, "subtype": None}, + "product_type": {"type": str, "subtype": None}, + "rating": {"type": _rating, "subtype": None}, + "releaseDate": {"type": str, "subtype": None}, + "requiresRosetta": {"type": bool, "subtype": None}, + "runsOnAppleSilicon": {"type": bool, "subtype": None}, + "runsOnIntel": {"type": bool, "subtype": None}, + "s": {"type": int, "subtype": None}, + "software_platform": {"type": str, "subtype": None}, + "softwareIcon57x57URL": {"type": str, "subtype": None}, + "softwareIconNeedsShine": {"type": bool, "subtype": None}, + "softwareSupportedDeviceIds": {"type": list, "subtype": int}, + "softwareVersionBundleId": {"type": str, "subtype": None}, + "softwareVersionExternalIdentifier": {"type": int, "subtype": None}, + "softwareVersionExternalIdentifiers": {"type": list, "subtype": int}, + "subgenres": {"type": list, "subtype": _subgenres}, + "vendorId": {"type": int, "subtype": None}, + "drmVersionNumber": {"type": int, "subtype": None}, + "versionRestrictions": {"type": int, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "MacUIRequiredDeviceCapabilities": { + "required": True, + }, + "UIRequiredDeviceCapabilities": { + "required": True, + }, + "artistId": { + "required": True, + }, + "artistName": { + "required": True, + }, + "bundleDisplayName": { + "required": True, + }, + "bundleShortVersionString": { + "required": True, + }, + "bundleVersion": { + "required": True, + }, + "copyright": { + "required": True, + }, + "fileExtension": { + "required": True, + }, + "gameCenterEnabled": { + "required": True, + }, + "gameCenterEverEnabled": { + "required": True, + }, + "genre": { + "required": True, + }, + "genreId": { + "required": True, + }, + "itemId": { + "required": True, + }, + "itemName": { + "required": True, + }, + "kind": { + "required": True, + }, + "playlistName": { + "required": True, + }, + "product_type": { + "required": True, + }, + "rating": { + "required": True, + }, + "releaseDate": { + "required": True, + }, + "requiresRosetta": { + "required": True, + }, + "runsOnAppleSilicon": { + "required": True, + }, + "runsOnIntel": { + "required": True, + }, + "s": { + "required": True, + }, + "software_platform": { + "required": True, + }, + "softwareIcon57x57URL": { + "required": True, + }, + "softwareIconNeedsShine": { + "required": True, + }, + "softwareSupportedDeviceIds": { + "required": True, + }, + "softwareVersionBundleId": { + "required": True, + }, + "softwareVersionExternalIdentifier": { + "required": True, + }, + "softwareVersionExternalIdentifiers": { + "required": True, + }, + "subgenres": { + "required": True, + }, + "vendorId": { + "required": True, + }, + "drmVersionNumber": { + "required": True, + }, + "versionRestrictions": { + "required": True, + }, + } + + def __init__( + self, + MacUIRequiredDeviceCapabilities: _MacUIRequiredDeviceCapabilities = None, + UIRequiredDeviceCapabilities: _UIRequiredDeviceCapabilities = None, + artistId: int = None, + artistName: str = None, + bundleDisplayName: str = None, + bundleShortVersionString: str = None, + bundleVersion: str = None, + copyright: str = None, + fileExtension: str = None, + gameCenterEnabled: bool = None, + gameCenterEverEnabled: bool = None, + genre: str = None, + genreId: int = None, + itemId: int = None, + itemName: str = None, + kind: str = None, + playlistName: str = None, + product_type: str = None, + rating: _rating = None, + releaseDate: str = None, + requiresRosetta: bool = None, + runsOnAppleSilicon: bool = None, + runsOnIntel: bool = None, + s: int = None, + software_platform: str = None, + softwareIcon57x57URL: str = None, + softwareIconNeedsShine: bool = None, + softwareSupportedDeviceIds: List[int] = None, + softwareVersionBundleId: str = None, + softwareVersionExternalIdentifier: int = None, + softwareVersionExternalIdentifiers: List[int] = None, + subgenres: List[_subgenres] = None, + vendorId: int = None, + drmVersionNumber: int = None, + versionRestrictions: int = None, + ): + pass + self.__MacUIRequiredDeviceCapabilities = MacUIRequiredDeviceCapabilities + self.__UIRequiredDeviceCapabilities = UIRequiredDeviceCapabilities + self.__artistId = artistId + self.__artistName = artistName + self.__bundleDisplayName = bundleDisplayName + self.__bundleShortVersionString = bundleShortVersionString + self.__bundleVersion = bundleVersion + self.__copyright = copyright + self.__fileExtension = fileExtension + self.__gameCenterEnabled = gameCenterEnabled + self.__gameCenterEverEnabled = gameCenterEverEnabled + self.__genre = genre + self.__genreId = genreId + self.__itemId = itemId + self.__itemName = itemName + self.__kind = kind + self.__playlistName = playlistName + self.__product_type = product_type + self.__rating = rating + self.__releaseDate = releaseDate + self.__requiresRosetta = requiresRosetta + self.__runsOnAppleSilicon = runsOnAppleSilicon + self.__runsOnIntel = runsOnIntel + self.__s = s + self.__software_platform = software_platform + self.__softwareIcon57x57URL = softwareIcon57x57URL + self.__softwareIconNeedsShine = softwareIconNeedsShine + self.__softwareSupportedDeviceIds = softwareSupportedDeviceIds + self.__softwareVersionBundleId = softwareVersionBundleId + self.__softwareVersionExternalIdentifier = ( + softwareVersionExternalIdentifier + ) + self.__softwareVersionExternalIdentifiers = ( + softwareVersionExternalIdentifiers + ) + self.__subgenres = subgenres + self.__vendorId = vendorId + self.__drmVersionNumber = drmVersionNumber + self.__versionRestrictions = versionRestrictions + + def _get_MacUIRequiredDeviceCapabilities(self): + return self.__MacUIRequiredDeviceCapabilities + + def _set_MacUIRequiredDeviceCapabilities(self, value): + if not isinstance( + value, + StoreDownloadResp._songList._metadata._MacUIRequiredDeviceCapabilities, + ): + raise TypeError( + "MacUIRequiredDeviceCapabilities must be StoreDownloadResp._songList._metadata._MacUIRequiredDeviceCapabilities" + ) + + self.__MacUIRequiredDeviceCapabilities = value + + MacUIRequiredDeviceCapabilities = property( + _get_MacUIRequiredDeviceCapabilities, + _set_MacUIRequiredDeviceCapabilities, + ) + + def _get_UIRequiredDeviceCapabilities(self): + return self.__UIRequiredDeviceCapabilities + + def _set_UIRequiredDeviceCapabilities(self, value): + if not isinstance( + value, + StoreDownloadResp._songList._metadata._UIRequiredDeviceCapabilities, + ): + raise TypeError( + "UIRequiredDeviceCapabilities must be StoreDownloadResp._songList._metadata._UIRequiredDeviceCapabilities" + ) + + self.__UIRequiredDeviceCapabilities = value + + UIRequiredDeviceCapabilities = property( + _get_UIRequiredDeviceCapabilities, _set_UIRequiredDeviceCapabilities + ) + + def _get_artistId(self): + return self.__artistId + + def _set_artistId(self, value): + if not isinstance(value, int): + raise TypeError("artistId must be int") + + self.__artistId = value + + artistId = property(_get_artistId, _set_artistId) + + def _get_artistName(self): + return self.__artistName + + def _set_artistName(self, value): + if not isinstance(value, str): + raise TypeError("artistName must be str") + + self.__artistName = value + + artistName = property(_get_artistName, _set_artistName) + + def _get_bundleDisplayName(self): + return self.__bundleDisplayName + + def _set_bundleDisplayName(self, value): + if not isinstance(value, str): + raise TypeError("bundleDisplayName must be str") + + self.__bundleDisplayName = value + + bundleDisplayName = property(_get_bundleDisplayName, _set_bundleDisplayName) + + def _get_bundleShortVersionString(self): + return self.__bundleShortVersionString + + def _set_bundleShortVersionString(self, value): + if not isinstance(value, str): + raise TypeError("bundleShortVersionString must be str") + + self.__bundleShortVersionString = value + + bundleShortVersionString = property( + _get_bundleShortVersionString, _set_bundleShortVersionString + ) + + def _get_bundleVersion(self): + return self.__bundleVersion + + def _set_bundleVersion(self, value): + if not isinstance(value, str): + raise TypeError("bundleVersion must be str") + + self.__bundleVersion = value + + bundleVersion = property(_get_bundleVersion, _set_bundleVersion) + + def _get_copyright(self): + return self.__copyright + + def _set_copyright(self, value): + if not isinstance(value, str): + raise TypeError("copyright must be str") + + self.__copyright = value + + copyright = property(_get_copyright, _set_copyright) + + def _get_fileExtension(self): + return self.__fileExtension + + def _set_fileExtension(self, value): + if not isinstance(value, str): + raise TypeError("fileExtension must be str") + + self.__fileExtension = value + + fileExtension = property(_get_fileExtension, _set_fileExtension) + + def _get_gameCenterEnabled(self): + return self.__gameCenterEnabled + + def _set_gameCenterEnabled(self, value): + if not isinstance(value, bool): + raise TypeError("gameCenterEnabled must be bool") + + self.__gameCenterEnabled = value + + gameCenterEnabled = property(_get_gameCenterEnabled, _set_gameCenterEnabled) + + def _get_gameCenterEverEnabled(self): + return self.__gameCenterEverEnabled + + def _set_gameCenterEverEnabled(self, value): + if not isinstance(value, bool): + raise TypeError("gameCenterEverEnabled must be bool") + + self.__gameCenterEverEnabled = value + + gameCenterEverEnabled = property( + _get_gameCenterEverEnabled, _set_gameCenterEverEnabled + ) + + def _get_genre(self): + return self.__genre + + def _set_genre(self, value): + if not isinstance(value, str): + raise TypeError("genre must be str") + + self.__genre = value + + genre = property(_get_genre, _set_genre) + + def _get_genreId(self): + return self.__genreId + + def _set_genreId(self, value): + if not isinstance(value, int): + raise TypeError("genreId must be int") + + self.__genreId = value + + genreId = property(_get_genreId, _set_genreId) + + def _get_itemId(self): + return self.__itemId + + def _set_itemId(self, value): + if not isinstance(value, int): + raise TypeError("itemId must be int") + + self.__itemId = value + + itemId = property(_get_itemId, _set_itemId) + + def _get_itemName(self): + return self.__itemName + + def _set_itemName(self, value): + if not isinstance(value, str): + raise TypeError("itemName must be str") + + self.__itemName = value + + itemName = property(_get_itemName, _set_itemName) + + def _get_kind(self): + return self.__kind + + def _set_kind(self, value): + if not isinstance(value, str): + raise TypeError("kind must be str") + + self.__kind = value + + kind = property(_get_kind, _set_kind) + + def _get_playlistName(self): + return self.__playlistName + + def _set_playlistName(self, value): + if not isinstance(value, str): + raise TypeError("playlistName must be str") + + self.__playlistName = value + + playlistName = property(_get_playlistName, _set_playlistName) + + def _get_product_type(self): + return self.__product_type + + def _set_product_type(self, value): + if not isinstance(value, str): + raise TypeError("product_type must be str") + + self.__product_type = value + + product_type = property(_get_product_type, _set_product_type) + + def _get_rating(self): + return self.__rating + + def _set_rating(self, value): + if not isinstance(value, StoreDownloadResp._songList._metadata._rating): + raise TypeError( + "rating must be StoreDownloadResp._songList._metadata._rating" + ) + + self.__rating = value + + rating = property(_get_rating, _set_rating) + + def _get_releaseDate(self): + return self.__releaseDate + + def _set_releaseDate(self, value): + if not isinstance(value, str): + raise TypeError("releaseDate must be str") + + self.__releaseDate = value + + releaseDate = property(_get_releaseDate, _set_releaseDate) + + def _get_requiresRosetta(self): + return self.__requiresRosetta + + def _set_requiresRosetta(self, value): + if not isinstance(value, bool): + raise TypeError("requiresRosetta must be bool") + + self.__requiresRosetta = value + + requiresRosetta = property(_get_requiresRosetta, _set_requiresRosetta) + + def _get_runsOnAppleSilicon(self): + return self.__runsOnAppleSilicon + + def _set_runsOnAppleSilicon(self, value): + if not isinstance(value, bool): + raise TypeError("runsOnAppleSilicon must be bool") + + self.__runsOnAppleSilicon = value + + runsOnAppleSilicon = property( + _get_runsOnAppleSilicon, _set_runsOnAppleSilicon + ) + + def _get_runsOnIntel(self): + return self.__runsOnIntel + + def _set_runsOnIntel(self, value): + if not isinstance(value, bool): + raise TypeError("runsOnIntel must be bool") + + self.__runsOnIntel = value + + runsOnIntel = property(_get_runsOnIntel, _set_runsOnIntel) + + def _get_s(self): + return self.__s + + def _set_s(self, value): + if not isinstance(value, int): + raise TypeError("s must be int") + + self.__s = value + + s = property(_get_s, _set_s) + + def _get_software_platform(self): + return self.__software_platform + + def _set_software_platform(self, value): + if not isinstance(value, str): + raise TypeError("software_platform must be str") + + self.__software_platform = value + + software_platform = property(_get_software_platform, _set_software_platform) + + def _get_softwareIcon57x57URL(self): + return self.__softwareIcon57x57URL + + def _set_softwareIcon57x57URL(self, value): + if not isinstance(value, str): + raise TypeError("softwareIcon57x57URL must be str") + + self.__softwareIcon57x57URL = value + + softwareIcon57x57URL = property( + _get_softwareIcon57x57URL, _set_softwareIcon57x57URL + ) + + def _get_softwareIconNeedsShine(self): + return self.__softwareIconNeedsShine + + def _set_softwareIconNeedsShine(self, value): + if not isinstance(value, bool): + raise TypeError("softwareIconNeedsShine must be bool") + + self.__softwareIconNeedsShine = value + + softwareIconNeedsShine = property( + _get_softwareIconNeedsShine, _set_softwareIconNeedsShine + ) + + def _get_softwareSupportedDeviceIds(self): + return self.__softwareSupportedDeviceIds + + def _set_softwareSupportedDeviceIds(self, value): + if not isinstance(value, list): + raise TypeError("softwareSupportedDeviceIds must be list") + if not all(isinstance(i, int) for i in value): + raise TypeError( + "softwareSupportedDeviceIds list values must be int" + ) + + self.__softwareSupportedDeviceIds = value + + softwareSupportedDeviceIds = property( + _get_softwareSupportedDeviceIds, _set_softwareSupportedDeviceIds + ) + + def _get_softwareVersionBundleId(self): + return self.__softwareVersionBundleId + + def _set_softwareVersionBundleId(self, value): + if not isinstance(value, str): + raise TypeError("softwareVersionBundleId must be str") + + self.__softwareVersionBundleId = value + + softwareVersionBundleId = property( + _get_softwareVersionBundleId, _set_softwareVersionBundleId + ) + + def _get_softwareVersionExternalIdentifier(self): + return self.__softwareVersionExternalIdentifier + + def _set_softwareVersionExternalIdentifier(self, value): + if not isinstance(value, int): + raise TypeError("softwareVersionExternalIdentifier must be int") + + self.__softwareVersionExternalIdentifier = value + + softwareVersionExternalIdentifier = property( + _get_softwareVersionExternalIdentifier, + _set_softwareVersionExternalIdentifier, + ) + + def _get_softwareVersionExternalIdentifiers(self): + return self.__softwareVersionExternalIdentifiers + + def _set_softwareVersionExternalIdentifiers(self, value): + if not isinstance(value, list): + raise TypeError("softwareVersionExternalIdentifiers must be list") + if not all(isinstance(i, int) for i in value): + raise TypeError( + "softwareVersionExternalIdentifiers list values must be int" + ) + + self.__softwareVersionExternalIdentifiers = value + + softwareVersionExternalIdentifiers = property( + _get_softwareVersionExternalIdentifiers, + _set_softwareVersionExternalIdentifiers, + ) + + def _get_subgenres(self): + return self.__subgenres + + def _set_subgenres(self, value): + if not isinstance(value, list): + raise TypeError("subgenres must be list") + if not all( + isinstance(i, StoreDownloadResp._songList._metadata._subgenres) + for i in value + ): + raise TypeError( + "subgenres list values must be StoreDownloadResp._songList._metadata._subgenres" + ) + + self.__subgenres = value + + subgenres = property(_get_subgenres, _set_subgenres) + + def _get_vendorId(self): + return self.__vendorId + + def _set_vendorId(self, value): + if not isinstance(value, int): + raise TypeError("vendorId must be int") + + self.__vendorId = value + + vendorId = property(_get_vendorId, _set_vendorId) + + def _get_drmVersionNumber(self): + return self.__drmVersionNumber + + def _set_drmVersionNumber(self, value): + if not isinstance(value, int): + raise TypeError("drmVersionNumber must be int") + + self.__drmVersionNumber = value + + drmVersionNumber = property(_get_drmVersionNumber, _set_drmVersionNumber) + + def _get_versionRestrictions(self): + return self.__versionRestrictions + + def _set_versionRestrictions(self, value): + if not isinstance(value, int): + raise TypeError("versionRestrictions must be int") + + self.__versionRestrictions = value + + versionRestrictions = property( + _get_versionRestrictions, _set_versionRestrictions + ) + + @staticmethod + def from_dict(d): + v = {} + if "MacUIRequiredDeviceCapabilities" in d: + v["MacUIRequiredDeviceCapabilities"] = ( + StoreDownloadResp._songList._metadata._MacUIRequiredDeviceCapabilities.from_dict( + d["MacUIRequiredDeviceCapabilities"] + ) + if hasattr( + StoreDownloadResp._songList._metadata._MacUIRequiredDeviceCapabilities, + "from_dict", + ) + else d["MacUIRequiredDeviceCapabilities"] + ) + if "UIRequiredDeviceCapabilities" in d: + v["UIRequiredDeviceCapabilities"] = ( + StoreDownloadResp._songList._metadata._UIRequiredDeviceCapabilities.from_dict( + d["UIRequiredDeviceCapabilities"] + ) + if hasattr( + StoreDownloadResp._songList._metadata._UIRequiredDeviceCapabilities, + "from_dict", + ) + else d["UIRequiredDeviceCapabilities"] + ) + if "artistId" in d: + v["artistId"] = ( + int.from_dict(d["artistId"]) + if hasattr(int, "from_dict") + else d["artistId"] + ) + if "artistName" in d: + v["artistName"] = ( + str.from_dict(d["artistName"]) + if hasattr(str, "from_dict") + else d["artistName"] + ) + if "bundleDisplayName" in d: + v["bundleDisplayName"] = ( + str.from_dict(d["bundleDisplayName"]) + if hasattr(str, "from_dict") + else d["bundleDisplayName"] + ) + if "bundleShortVersionString" in d: + v["bundleShortVersionString"] = ( + str.from_dict(d["bundleShortVersionString"]) + if hasattr(str, "from_dict") + else d["bundleShortVersionString"] + ) + if "bundleVersion" in d: + v["bundleVersion"] = ( + str.from_dict(d["bundleVersion"]) + if hasattr(str, "from_dict") + else d["bundleVersion"] + ) + if "copyright" in d: + v["copyright"] = ( + str.from_dict(d["copyright"]) + if hasattr(str, "from_dict") + else d["copyright"] + ) + if "fileExtension" in d: + v["fileExtension"] = ( + str.from_dict(d["fileExtension"]) + if hasattr(str, "from_dict") + else d["fileExtension"] + ) + if "gameCenterEnabled" in d: + v["gameCenterEnabled"] = ( + bool.from_dict(d["gameCenterEnabled"]) + if hasattr(bool, "from_dict") + else d["gameCenterEnabled"] + ) + if "gameCenterEverEnabled" in d: + v["gameCenterEverEnabled"] = ( + bool.from_dict(d["gameCenterEverEnabled"]) + if hasattr(bool, "from_dict") + else d["gameCenterEverEnabled"] + ) + if "genre" in d: + v["genre"] = ( + str.from_dict(d["genre"]) + if hasattr(str, "from_dict") + else d["genre"] + ) + if "genreId" in d: + v["genreId"] = ( + int.from_dict(d["genreId"]) + if hasattr(int, "from_dict") + else d["genreId"] + ) + if "itemId" in d: + v["itemId"] = ( + int.from_dict(d["itemId"]) + if hasattr(int, "from_dict") + else d["itemId"] + ) + if "itemName" in d: + v["itemName"] = ( + str.from_dict(d["itemName"]) + if hasattr(str, "from_dict") + else d["itemName"] + ) + if "kind" in d: + v["kind"] = ( + str.from_dict(d["kind"]) + if hasattr(str, "from_dict") + else d["kind"] + ) + if "playlistName" in d: + v["playlistName"] = ( + str.from_dict(d["playlistName"]) + if hasattr(str, "from_dict") + else d["playlistName"] + ) + if "product-type" in d: + v["product_type"] = ( + str.from_dict(d["product-type"]) + if hasattr(str, "from_dict") + else d["product-type"] + ) + if "rating" in d: + v["rating"] = ( + StoreDownloadResp._songList._metadata._rating.from_dict( + d["rating"] + ) + if hasattr( + StoreDownloadResp._songList._metadata._rating, "from_dict" + ) + else d["rating"] + ) + if "releaseDate" in d: + v["releaseDate"] = ( + str.from_dict(d["releaseDate"]) + if hasattr(str, "from_dict") + else d["releaseDate"] + ) + if "requiresRosetta" in d: + v["requiresRosetta"] = ( + bool.from_dict(d["requiresRosetta"]) + if hasattr(bool, "from_dict") + else d["requiresRosetta"] + ) + if "runsOnAppleSilicon" in d: + v["runsOnAppleSilicon"] = ( + bool.from_dict(d["runsOnAppleSilicon"]) + if hasattr(bool, "from_dict") + else d["runsOnAppleSilicon"] + ) + if "runsOnIntel" in d: + v["runsOnIntel"] = ( + bool.from_dict(d["runsOnIntel"]) + if hasattr(bool, "from_dict") + else d["runsOnIntel"] + ) + if "s" in d: + v["s"] = ( + int.from_dict(d["s"]) if hasattr(int, "from_dict") else d["s"] + ) + if "software-platform" in d: + v["software_platform"] = ( + str.from_dict(d["software-platform"]) + if hasattr(str, "from_dict") + else d["software-platform"] + ) + if "softwareIcon57x57URL" in d: + v["softwareIcon57x57URL"] = ( + str.from_dict(d["softwareIcon57x57URL"]) + if hasattr(str, "from_dict") + else d["softwareIcon57x57URL"] + ) + if "softwareIconNeedsShine" in d: + v["softwareIconNeedsShine"] = ( + bool.from_dict(d["softwareIconNeedsShine"]) + if hasattr(bool, "from_dict") + else d["softwareIconNeedsShine"] + ) + if "softwareSupportedDeviceIds" in d: + v["softwareSupportedDeviceIds"] = [ + int.from_dict(p) if hasattr(int, "from_dict") else p + for p in d["softwareSupportedDeviceIds"] + ] + if "softwareVersionBundleId" in d: + v["softwareVersionBundleId"] = ( + str.from_dict(d["softwareVersionBundleId"]) + if hasattr(str, "from_dict") + else d["softwareVersionBundleId"] + ) + if "softwareVersionExternalIdentifier" in d: + v["softwareVersionExternalIdentifier"] = ( + int.from_dict(d["softwareVersionExternalIdentifier"]) + if hasattr(int, "from_dict") + else d["softwareVersionExternalIdentifier"] + ) + if "softwareVersionExternalIdentifiers" in d: + v["softwareVersionExternalIdentifiers"] = [ + int.from_dict(p) if hasattr(int, "from_dict") else p + for p in d["softwareVersionExternalIdentifiers"] + ] + if "subgenres" in d: + v["subgenres"] = [ + StoreDownloadResp._songList._metadata._subgenres.from_dict(p) + if hasattr( + StoreDownloadResp._songList._metadata._subgenres, + "from_dict", + ) + else p + for p in d["subgenres"] + ] + if "vendorId" in d: + v["vendorId"] = ( + int.from_dict(d["vendorId"]) + if hasattr(int, "from_dict") + else d["vendorId"] + ) + if "drmVersionNumber" in d: + v["drmVersionNumber"] = ( + int.from_dict(d["drmVersionNumber"]) + if hasattr(int, "from_dict") + else d["drmVersionNumber"] + ) + if "versionRestrictions" in d: + v["versionRestrictions"] = ( + int.from_dict(d["versionRestrictions"]) + if hasattr(int, "from_dict") + else d["versionRestrictions"] + ) + return StoreDownloadResp._songList._metadata(**v) + + def as_dict(self): + d = {} + if self.__MacUIRequiredDeviceCapabilities is not None: + d["MacUIRequiredDeviceCapabilities"] = ( + self.__MacUIRequiredDeviceCapabilities.as_dict() + if hasattr(self.__MacUIRequiredDeviceCapabilities, "as_dict") + else self.__MacUIRequiredDeviceCapabilities + ) + if self.__UIRequiredDeviceCapabilities is not None: + d["UIRequiredDeviceCapabilities"] = ( + self.__UIRequiredDeviceCapabilities.as_dict() + if hasattr(self.__UIRequiredDeviceCapabilities, "as_dict") + else self.__UIRequiredDeviceCapabilities + ) + if self.__artistId is not None: + d["artistId"] = ( + self.__artistId.as_dict() + if hasattr(self.__artistId, "as_dict") + else self.__artistId + ) + if self.__artistName is not None: + d["artistName"] = ( + self.__artistName.as_dict() + if hasattr(self.__artistName, "as_dict") + else self.__artistName + ) + if self.__bundleDisplayName is not None: + d["bundleDisplayName"] = ( + self.__bundleDisplayName.as_dict() + if hasattr(self.__bundleDisplayName, "as_dict") + else self.__bundleDisplayName + ) + if self.__bundleShortVersionString is not None: + d["bundleShortVersionString"] = ( + self.__bundleShortVersionString.as_dict() + if hasattr(self.__bundleShortVersionString, "as_dict") + else self.__bundleShortVersionString + ) + if self.__bundleVersion is not None: + d["bundleVersion"] = ( + self.__bundleVersion.as_dict() + if hasattr(self.__bundleVersion, "as_dict") + else self.__bundleVersion + ) + if self.__copyright is not None: + d["copyright"] = ( + self.__copyright.as_dict() + if hasattr(self.__copyright, "as_dict") + else self.__copyright + ) + if self.__fileExtension is not None: + d["fileExtension"] = ( + self.__fileExtension.as_dict() + if hasattr(self.__fileExtension, "as_dict") + else self.__fileExtension + ) + if self.__gameCenterEnabled is not None: + d["gameCenterEnabled"] = ( + self.__gameCenterEnabled.as_dict() + if hasattr(self.__gameCenterEnabled, "as_dict") + else self.__gameCenterEnabled + ) + if self.__gameCenterEverEnabled is not None: + d["gameCenterEverEnabled"] = ( + self.__gameCenterEverEnabled.as_dict() + if hasattr(self.__gameCenterEverEnabled, "as_dict") + else self.__gameCenterEverEnabled + ) + if self.__genre is not None: + d["genre"] = ( + self.__genre.as_dict() + if hasattr(self.__genre, "as_dict") + else self.__genre + ) + if self.__genreId is not None: + d["genreId"] = ( + self.__genreId.as_dict() + if hasattr(self.__genreId, "as_dict") + else self.__genreId + ) + if self.__itemId is not None: + d["itemId"] = ( + self.__itemId.as_dict() + if hasattr(self.__itemId, "as_dict") + else self.__itemId + ) + if self.__itemName is not None: + d["itemName"] = ( + self.__itemName.as_dict() + if hasattr(self.__itemName, "as_dict") + else self.__itemName + ) + if self.__kind is not None: + d["kind"] = ( + self.__kind.as_dict() + if hasattr(self.__kind, "as_dict") + else self.__kind + ) + if self.__playlistName is not None: + d["playlistName"] = ( + self.__playlistName.as_dict() + if hasattr(self.__playlistName, "as_dict") + else self.__playlistName + ) + if self.__product_type is not None: + d["product-type"] = ( + self.__product_type.as_dict() + if hasattr(self.__product_type, "as_dict") + else self.__product_type + ) + if self.__rating is not None: + d["rating"] = ( + self.__rating.as_dict() + if hasattr(self.__rating, "as_dict") + else self.__rating + ) + if self.__releaseDate is not None: + d["releaseDate"] = ( + self.__releaseDate.as_dict() + if hasattr(self.__releaseDate, "as_dict") + else self.__releaseDate + ) + if self.__requiresRosetta is not None: + d["requiresRosetta"] = ( + self.__requiresRosetta.as_dict() + if hasattr(self.__requiresRosetta, "as_dict") + else self.__requiresRosetta + ) + if self.__runsOnAppleSilicon is not None: + d["runsOnAppleSilicon"] = ( + self.__runsOnAppleSilicon.as_dict() + if hasattr(self.__runsOnAppleSilicon, "as_dict") + else self.__runsOnAppleSilicon + ) + if self.__runsOnIntel is not None: + d["runsOnIntel"] = ( + self.__runsOnIntel.as_dict() + if hasattr(self.__runsOnIntel, "as_dict") + else self.__runsOnIntel + ) + if self.__s is not None: + d["s"] = ( + self.__s.as_dict() if hasattr(self.__s, "as_dict") else self.__s + ) + if self.__software_platform is not None: + d["software-platform"] = ( + self.__software_platform.as_dict() + if hasattr(self.__software_platform, "as_dict") + else self.__software_platform + ) + if self.__softwareIcon57x57URL is not None: + d["softwareIcon57x57URL"] = ( + self.__softwareIcon57x57URL.as_dict() + if hasattr(self.__softwareIcon57x57URL, "as_dict") + else self.__softwareIcon57x57URL + ) + if self.__softwareIconNeedsShine is not None: + d["softwareIconNeedsShine"] = ( + self.__softwareIconNeedsShine.as_dict() + if hasattr(self.__softwareIconNeedsShine, "as_dict") + else self.__softwareIconNeedsShine + ) + if self.__softwareSupportedDeviceIds is not None: + d["softwareSupportedDeviceIds"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__softwareSupportedDeviceIds + ] + if self.__softwareVersionBundleId is not None: + d["softwareVersionBundleId"] = ( + self.__softwareVersionBundleId.as_dict() + if hasattr(self.__softwareVersionBundleId, "as_dict") + else self.__softwareVersionBundleId + ) + if self.__softwareVersionExternalIdentifier is not None: + d["softwareVersionExternalIdentifier"] = ( + self.__softwareVersionExternalIdentifier.as_dict() + if hasattr(self.__softwareVersionExternalIdentifier, "as_dict") + else self.__softwareVersionExternalIdentifier + ) + if self.__softwareVersionExternalIdentifiers is not None: + d["softwareVersionExternalIdentifiers"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__softwareVersionExternalIdentifiers + ] + if self.__subgenres is not None: + d["subgenres"] = [ + p.as_dict() if hasattr(p, "as_dict") else p + for p in self.__subgenres + ] + if self.__vendorId is not None: + d["vendorId"] = ( + self.__vendorId.as_dict() + if hasattr(self.__vendorId, "as_dict") + else self.__vendorId + ) + if self.__drmVersionNumber is not None: + d["drmVersionNumber"] = ( + self.__drmVersionNumber.as_dict() + if hasattr(self.__drmVersionNumber, "as_dict") + else self.__drmVersionNumber + ) + if self.__versionRestrictions is not None: + d["versionRestrictions"] = ( + self.__versionRestrictions.as_dict() + if hasattr(self.__versionRestrictions, "as_dict") + else self.__versionRestrictions + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__MacUIRequiredDeviceCapabilities[:20] + if isinstance(self.__MacUIRequiredDeviceCapabilities, bytes) + else self.__MacUIRequiredDeviceCapabilities + ), + limitedRepr( + self.__UIRequiredDeviceCapabilities[:20] + if isinstance(self.__UIRequiredDeviceCapabilities, bytes) + else self.__UIRequiredDeviceCapabilities + ), + limitedRepr( + self.__artistId[:20] + if isinstance(self.__artistId, bytes) + else self.__artistId + ), + limitedRepr( + self.__artistName[:20] + if isinstance(self.__artistName, bytes) + else self.__artistName + ), + limitedRepr( + self.__bundleDisplayName[:20] + if isinstance(self.__bundleDisplayName, bytes) + else self.__bundleDisplayName + ), + limitedRepr( + self.__bundleShortVersionString[:20] + if isinstance(self.__bundleShortVersionString, bytes) + else self.__bundleShortVersionString + ), + limitedRepr( + self.__bundleVersion[:20] + if isinstance(self.__bundleVersion, bytes) + else self.__bundleVersion + ), + limitedRepr( + self.__copyright[:20] + if isinstance(self.__copyright, bytes) + else self.__copyright + ), + limitedRepr( + self.__fileExtension[:20] + if isinstance(self.__fileExtension, bytes) + else self.__fileExtension + ), + limitedRepr( + self.__gameCenterEnabled[:20] + if isinstance(self.__gameCenterEnabled, bytes) + else self.__gameCenterEnabled + ), + limitedRepr( + self.__gameCenterEverEnabled[:20] + if isinstance(self.__gameCenterEverEnabled, bytes) + else self.__gameCenterEverEnabled + ), + limitedRepr( + self.__genre[:20] + if isinstance(self.__genre, bytes) + else self.__genre + ), + limitedRepr( + self.__genreId[:20] + if isinstance(self.__genreId, bytes) + else self.__genreId + ), + limitedRepr( + self.__itemId[:20] + if isinstance(self.__itemId, bytes) + else self.__itemId + ), + limitedRepr( + self.__itemName[:20] + if isinstance(self.__itemName, bytes) + else self.__itemName + ), + limitedRepr( + self.__kind[:20] + if isinstance(self.__kind, bytes) + else self.__kind + ), + limitedRepr( + self.__playlistName[:20] + if isinstance(self.__playlistName, bytes) + else self.__playlistName + ), + limitedRepr( + self.__product_type[:20] + if isinstance(self.__product_type, bytes) + else self.__product_type + ), + limitedRepr( + self.__rating[:20] + if isinstance(self.__rating, bytes) + else self.__rating + ), + limitedRepr( + self.__releaseDate[:20] + if isinstance(self.__releaseDate, bytes) + else self.__releaseDate + ), + limitedRepr( + self.__requiresRosetta[:20] + if isinstance(self.__requiresRosetta, bytes) + else self.__requiresRosetta + ), + limitedRepr( + self.__runsOnAppleSilicon[:20] + if isinstance(self.__runsOnAppleSilicon, bytes) + else self.__runsOnAppleSilicon + ), + limitedRepr( + self.__runsOnIntel[:20] + if isinstance(self.__runsOnIntel, bytes) + else self.__runsOnIntel + ), + limitedRepr( + self.__s[:20] if isinstance(self.__s, bytes) else self.__s + ), + limitedRepr( + self.__software_platform[:20] + if isinstance(self.__software_platform, bytes) + else self.__software_platform + ), + limitedRepr( + self.__softwareIcon57x57URL[:20] + if isinstance(self.__softwareIcon57x57URL, bytes) + else self.__softwareIcon57x57URL + ), + limitedRepr( + self.__softwareIconNeedsShine[:20] + if isinstance(self.__softwareIconNeedsShine, bytes) + else self.__softwareIconNeedsShine + ), + limitedRepr( + self.__softwareSupportedDeviceIds[:20] + if isinstance(self.__softwareSupportedDeviceIds, bytes) + else self.__softwareSupportedDeviceIds + ), + limitedRepr( + self.__softwareVersionBundleId[:20] + if isinstance(self.__softwareVersionBundleId, bytes) + else self.__softwareVersionBundleId + ), + limitedRepr( + self.__softwareVersionExternalIdentifier[:20] + if isinstance(self.__softwareVersionExternalIdentifier, bytes) + else self.__softwareVersionExternalIdentifier + ), + limitedRepr( + self.__softwareVersionExternalIdentifiers[:20] + if isinstance(self.__softwareVersionExternalIdentifiers, bytes) + else self.__softwareVersionExternalIdentifiers + ), + limitedRepr( + self.__subgenres[:20] + if isinstance(self.__subgenres, bytes) + else self.__subgenres + ), + limitedRepr( + self.__vendorId[:20] + if isinstance(self.__vendorId, bytes) + else self.__vendorId + ), + limitedRepr( + self.__drmVersionNumber[:20] + if isinstance(self.__drmVersionNumber, bytes) + else self.__drmVersionNumber + ), + limitedRepr( + self.__versionRestrictions[:20] + if isinstance(self.__versionRestrictions, bytes) + else self.__versionRestrictions + ), + ) + + _types_map = { + "songId": {"type": int, "subtype": None}, + "URL": {"type": str, "subtype": None}, + "downloadKey": {"type": str, "subtype": None}, + "artworkURL": {"type": str, "subtype": None}, + "artwork_urls": {"type": _artwork_urls, "subtype": None}, + "md5": {"type": str, "subtype": None}, + "chunks": {"type": _chunks, "subtype": None}, + "isStreamable": {"type": bool, "subtype": None}, + "uncompressedSize": {"type": str, "subtype": None}, + "sinfs": {"type": list, "subtype": _sinfs}, + "purchaseDate": {"type": str, "subtype": None}, + "download_id": {"type": str, "subtype": None}, + "is_in_queue": {"type": bool, "subtype": None}, + "asset_info": {"type": _asset_info, "subtype": None}, + "metadata": {"type": _metadata, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "songId": { + "required": True, + }, + "URL": { + "required": True, + }, + "downloadKey": { + "required": True, + }, + "artworkURL": { + "required": True, + }, + "artwork_urls": { + "required": True, + }, + "md5": { + "required": True, + }, + "chunks": { + "required": True, + }, + "isStreamable": { + "required": True, + }, + "uncompressedSize": { + "required": True, + }, + "sinfs": { + "required": True, + }, + "purchaseDate": { + "required": True, + }, + "download_id": { + "required": True, + }, + "is_in_queue": { + "required": True, + }, + "asset_info": { + "required": True, + }, + "metadata": { + "required": True, + }, + } + + def __init__( + self, + songId: int = None, + URL: str = None, + downloadKey: str = None, + artworkURL: str = None, + artwork_urls: _artwork_urls = None, + md5: str = None, + chunks: _chunks = None, + isStreamable: bool = None, + uncompressedSize: str = None, + sinfs: List[_sinfs] = None, + purchaseDate: str = None, + download_id: str = None, + is_in_queue: bool = None, + asset_info: _asset_info = None, + metadata: _metadata = None, + ): + pass + self.__songId = songId + self.__URL = URL + self.__downloadKey = downloadKey + self.__artworkURL = artworkURL + self.__artwork_urls = artwork_urls + self.__md5 = md5 + self.__chunks = chunks + self.__isStreamable = isStreamable + self.__uncompressedSize = uncompressedSize + self.__sinfs = sinfs + self.__purchaseDate = purchaseDate + self.__download_id = download_id + self.__is_in_queue = is_in_queue + self.__asset_info = asset_info + self.__metadata = metadata + + def _get_songId(self): + return self.__songId + + def _set_songId(self, value): + if not isinstance(value, int): + raise TypeError("songId must be int") + + self.__songId = value + + songId = property(_get_songId, _set_songId) + + def _get_URL(self): + return self.__URL + + def _set_URL(self, value): + if not isinstance(value, str): + raise TypeError("URL must be str") + + self.__URL = value + + URL = property(_get_URL, _set_URL) + + def _get_downloadKey(self): + return self.__downloadKey + + def _set_downloadKey(self, value): + if not isinstance(value, str): + raise TypeError("downloadKey must be str") + + self.__downloadKey = value + + downloadKey = property(_get_downloadKey, _set_downloadKey) + + def _get_artworkURL(self): + return self.__artworkURL + + def _set_artworkURL(self, value): + if not isinstance(value, str): + raise TypeError("artworkURL must be str") + + self.__artworkURL = value + + artworkURL = property(_get_artworkURL, _set_artworkURL) + + def _get_artwork_urls(self): + return self.__artwork_urls + + def _set_artwork_urls(self, value): + if not isinstance(value, StoreDownloadResp._songList._artwork_urls): + raise TypeError( + "artwork_urls must be StoreDownloadResp._songList._artwork_urls" + ) + + self.__artwork_urls = value + + artwork_urls = property(_get_artwork_urls, _set_artwork_urls) + + def _get_md5(self): + return self.__md5 + + def _set_md5(self, value): + if not isinstance(value, str): + raise TypeError("md5 must be str") + + self.__md5 = value + + md5 = property(_get_md5, _set_md5) + + def _get_chunks(self): + return self.__chunks + + def _set_chunks(self, value): + if not isinstance(value, StoreDownloadResp._songList._chunks): + raise TypeError("chunks must be StoreDownloadResp._songList._chunks") + + self.__chunks = value + + chunks = property(_get_chunks, _set_chunks) + + def _get_isStreamable(self): + return self.__isStreamable + + def _set_isStreamable(self, value): + if not isinstance(value, bool): + raise TypeError("isStreamable must be bool") + + self.__isStreamable = value + + isStreamable = property(_get_isStreamable, _set_isStreamable) + + def _get_uncompressedSize(self): + return self.__uncompressedSize + + def _set_uncompressedSize(self, value): + if not isinstance(value, str): + raise TypeError("uncompressedSize must be str") + + self.__uncompressedSize = value + + uncompressedSize = property(_get_uncompressedSize, _set_uncompressedSize) + + def _get_sinfs(self): + return self.__sinfs + + def _set_sinfs(self, value): + if not isinstance(value, list): + raise TypeError("sinfs must be list") + if not all( + isinstance(i, StoreDownloadResp._songList._sinfs) for i in value + ): + raise TypeError( + "sinfs list values must be StoreDownloadResp._songList._sinfs" + ) + + self.__sinfs = value + + sinfs = property(_get_sinfs, _set_sinfs) + + def _get_purchaseDate(self): + return self.__purchaseDate + + def _set_purchaseDate(self, value): + if not isinstance(value, str): + raise TypeError("purchaseDate must be str") + + self.__purchaseDate = value + + purchaseDate = property(_get_purchaseDate, _set_purchaseDate) + + def _get_download_id(self): + return self.__download_id + + def _set_download_id(self, value): + if not isinstance(value, str): + raise TypeError("download_id must be str") + + self.__download_id = value + + download_id = property(_get_download_id, _set_download_id) + + def _get_is_in_queue(self): + return self.__is_in_queue + + def _set_is_in_queue(self, value): + if not isinstance(value, bool): + raise TypeError("is_in_queue must be bool") + + self.__is_in_queue = value + + is_in_queue = property(_get_is_in_queue, _set_is_in_queue) + + def _get_asset_info(self): + return self.__asset_info + + def _set_asset_info(self, value): + if not isinstance(value, StoreDownloadResp._songList._asset_info): + raise TypeError( + "asset_info must be StoreDownloadResp._songList._asset_info" + ) + + self.__asset_info = value + + asset_info = property(_get_asset_info, _set_asset_info) + + def _get_metadata(self): + return self.__metadata + + def _set_metadata(self, value): + if not isinstance(value, StoreDownloadResp._songList._metadata): + raise TypeError( + "metadata must be StoreDownloadResp._songList._metadata" + ) + + self.__metadata = value + + metadata = property(_get_metadata, _set_metadata) + + @staticmethod + def from_dict(d): + v = {} + if "songId" in d: + v["songId"] = ( + int.from_dict(d["songId"]) + if hasattr(int, "from_dict") + else d["songId"] + ) + if "URL" in d: + v["URL"] = ( + str.from_dict(d["URL"]) if hasattr(str, "from_dict") else d["URL"] + ) + if "downloadKey" in d: + v["downloadKey"] = ( + str.from_dict(d["downloadKey"]) + if hasattr(str, "from_dict") + else d["downloadKey"] + ) + if "artworkURL" in d: + v["artworkURL"] = ( + str.from_dict(d["artworkURL"]) + if hasattr(str, "from_dict") + else d["artworkURL"] + ) + if "artwork-urls" in d: + v["artwork_urls"] = ( + StoreDownloadResp._songList._artwork_urls.from_dict( + d["artwork-urls"] + ) + if hasattr(StoreDownloadResp._songList._artwork_urls, "from_dict") + else d["artwork-urls"] + ) + if "md5" in d: + v["md5"] = ( + str.from_dict(d["md5"]) if hasattr(str, "from_dict") else d["md5"] + ) + if "chunks" in d: + v["chunks"] = ( + StoreDownloadResp._songList._chunks.from_dict(d["chunks"]) + if hasattr(StoreDownloadResp._songList._chunks, "from_dict") + else d["chunks"] + ) + if "isStreamable" in d: + v["isStreamable"] = ( + bool.from_dict(d["isStreamable"]) + if hasattr(bool, "from_dict") + else d["isStreamable"] + ) + if "uncompressedSize" in d: + v["uncompressedSize"] = ( + str.from_dict(d["uncompressedSize"]) + if hasattr(str, "from_dict") + else d["uncompressedSize"] + ) + if "sinfs" in d: + v["sinfs"] = [ + StoreDownloadResp._songList._sinfs.from_dict(p) + if hasattr(StoreDownloadResp._songList._sinfs, "from_dict") + else p + for p in d["sinfs"] + ] + if "purchaseDate" in d: + v["purchaseDate"] = ( + str.from_dict(d["purchaseDate"]) + if hasattr(str, "from_dict") + else d["purchaseDate"] + ) + if "download-id" in d: + v["download_id"] = ( + str.from_dict(d["download-id"]) + if hasattr(str, "from_dict") + else d["download-id"] + ) + if "is-in-queue" in d: + v["is_in_queue"] = ( + bool.from_dict(d["is-in-queue"]) + if hasattr(bool, "from_dict") + else d["is-in-queue"] + ) + if "asset-info" in d: + v["asset_info"] = ( + StoreDownloadResp._songList._asset_info.from_dict(d["asset-info"]) + if hasattr(StoreDownloadResp._songList._asset_info, "from_dict") + else d["asset-info"] + ) + if "metadata" in d: + v["metadata"] = ( + StoreDownloadResp._songList._metadata.from_dict(d["metadata"]) + if hasattr(StoreDownloadResp._songList._metadata, "from_dict") + else d["metadata"] + ) + return StoreDownloadResp._songList(**v) + + def as_dict(self): + d = {} + if self.__songId is not None: + d["songId"] = ( + self.__songId.as_dict() + if hasattr(self.__songId, "as_dict") + else self.__songId + ) + if self.__URL is not None: + d["URL"] = ( + self.__URL.as_dict() + if hasattr(self.__URL, "as_dict") + else self.__URL + ) + if self.__downloadKey is not None: + d["downloadKey"] = ( + self.__downloadKey.as_dict() + if hasattr(self.__downloadKey, "as_dict") + else self.__downloadKey + ) + if self.__artworkURL is not None: + d["artworkURL"] = ( + self.__artworkURL.as_dict() + if hasattr(self.__artworkURL, "as_dict") + else self.__artworkURL + ) + if self.__artwork_urls is not None: + d["artwork-urls"] = ( + self.__artwork_urls.as_dict() + if hasattr(self.__artwork_urls, "as_dict") + else self.__artwork_urls + ) + if self.__md5 is not None: + d["md5"] = ( + self.__md5.as_dict() + if hasattr(self.__md5, "as_dict") + else self.__md5 + ) + if self.__chunks is not None: + d["chunks"] = ( + self.__chunks.as_dict() + if hasattr(self.__chunks, "as_dict") + else self.__chunks + ) + if self.__isStreamable is not None: + d["isStreamable"] = ( + self.__isStreamable.as_dict() + if hasattr(self.__isStreamable, "as_dict") + else self.__isStreamable + ) + if self.__uncompressedSize is not None: + d["uncompressedSize"] = ( + self.__uncompressedSize.as_dict() + if hasattr(self.__uncompressedSize, "as_dict") + else self.__uncompressedSize + ) + if self.__sinfs is not None: + d["sinfs"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__sinfs + ] + if self.__purchaseDate is not None: + d["purchaseDate"] = ( + self.__purchaseDate.as_dict() + if hasattr(self.__purchaseDate, "as_dict") + else self.__purchaseDate + ) + if self.__download_id is not None: + d["download-id"] = ( + self.__download_id.as_dict() + if hasattr(self.__download_id, "as_dict") + else self.__download_id + ) + if self.__is_in_queue is not None: + d["is-in-queue"] = ( + self.__is_in_queue.as_dict() + if hasattr(self.__is_in_queue, "as_dict") + else self.__is_in_queue + ) + if self.__asset_info is not None: + d["asset-info"] = ( + self.__asset_info.as_dict() + if hasattr(self.__asset_info, "as_dict") + else self.__asset_info + ) + if self.__metadata is not None: + d["metadata"] = ( + self.__metadata.as_dict() + if hasattr(self.__metadata, "as_dict") + else self.__metadata + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__songId[:20] + if isinstance(self.__songId, bytes) + else self.__songId + ), + limitedRepr( + self.__URL[:20] if isinstance(self.__URL, bytes) else self.__URL + ), + limitedRepr( + self.__downloadKey[:20] + if isinstance(self.__downloadKey, bytes) + else self.__downloadKey + ), + limitedRepr( + self.__artworkURL[:20] + if isinstance(self.__artworkURL, bytes) + else self.__artworkURL + ), + limitedRepr( + self.__artwork_urls[:20] + if isinstance(self.__artwork_urls, bytes) + else self.__artwork_urls + ), + limitedRepr( + self.__md5[:20] if isinstance(self.__md5, bytes) else self.__md5 + ), + limitedRepr( + self.__chunks[:20] + if isinstance(self.__chunks, bytes) + else self.__chunks + ), + limitedRepr( + self.__isStreamable[:20] + if isinstance(self.__isStreamable, bytes) + else self.__isStreamable + ), + limitedRepr( + self.__uncompressedSize[:20] + if isinstance(self.__uncompressedSize, bytes) + else self.__uncompressedSize + ), + limitedRepr( + self.__sinfs[:20] + if isinstance(self.__sinfs, bytes) + else self.__sinfs + ), + limitedRepr( + self.__purchaseDate[:20] + if isinstance(self.__purchaseDate, bytes) + else self.__purchaseDate + ), + limitedRepr( + self.__download_id[:20] + if isinstance(self.__download_id, bytes) + else self.__download_id + ), + limitedRepr( + self.__is_in_queue[:20] + if isinstance(self.__is_in_queue, bytes) + else self.__is_in_queue + ), + limitedRepr( + self.__asset_info[:20] + if isinstance(self.__asset_info, bytes) + else self.__asset_info + ), + limitedRepr( + self.__metadata[:20] + if isinstance(self.__metadata, bytes) + else self.__metadata + ), + ) + + class _metrics: + + _types_map = { + "itemIds": {"type": list, "subtype": int}, + "currency": {"type": str, "subtype": None}, + "exchangeRateToUSD": {"type": float, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "itemIds": { + "required": True, + }, + "currency": { + "required": True, + }, + "exchangeRateToUSD": { + "required": True, + }, + } + + def __init__( + self, + itemIds: List[int] = None, + currency: str = None, + exchangeRateToUSD: float = None, + ): + pass + self.__itemIds = itemIds + self.__currency = currency + self.__exchangeRateToUSD = exchangeRateToUSD + + def _get_itemIds(self): + return self.__itemIds + + def _set_itemIds(self, value): + if not isinstance(value, list): + raise TypeError("itemIds must be list") + if not all(isinstance(i, int) for i in value): + raise TypeError("itemIds list values must be int") + + self.__itemIds = value + + itemIds = property(_get_itemIds, _set_itemIds) + + def _get_currency(self): + return self.__currency + + def _set_currency(self, value): + if not isinstance(value, str): + raise TypeError("currency must be str") + + self.__currency = value + + currency = property(_get_currency, _set_currency) + + def _get_exchangeRateToUSD(self): + return self.__exchangeRateToUSD + + def _set_exchangeRateToUSD(self, value): + if not isinstance(value, float): + raise TypeError("exchangeRateToUSD must be float") + + self.__exchangeRateToUSD = value + + exchangeRateToUSD = property(_get_exchangeRateToUSD, _set_exchangeRateToUSD) + + @staticmethod + def from_dict(d): + v = {} + if "itemIds" in d: + v["itemIds"] = [ + int.from_dict(p) if hasattr(int, "from_dict") else p + for p in d["itemIds"] + ] + if "currency" in d: + v["currency"] = ( + str.from_dict(d["currency"]) + if hasattr(str, "from_dict") + else d["currency"] + ) + if "exchangeRateToUSD" in d: + v["exchangeRateToUSD"] = ( + float.from_dict(d["exchangeRateToUSD"]) + if hasattr(float, "from_dict") + else d["exchangeRateToUSD"] + ) + return StoreDownloadResp._metrics(**v) + + def as_dict(self): + d = {} + if self.__itemIds is not None: + d["itemIds"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__itemIds + ] + if self.__currency is not None: + d["currency"] = ( + self.__currency.as_dict() + if hasattr(self.__currency, "as_dict") + else self.__currency + ) + if self.__exchangeRateToUSD is not None: + d["exchangeRateToUSD"] = ( + self.__exchangeRateToUSD.as_dict() + if hasattr(self.__exchangeRateToUSD, "as_dict") + else self.__exchangeRateToUSD + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__itemIds[:20] + if isinstance(self.__itemIds, bytes) + else self.__itemIds + ), + limitedRepr( + self.__currency[:20] + if isinstance(self.__currency, bytes) + else self.__currency + ), + limitedRepr( + self.__exchangeRateToUSD[:20] + if isinstance(self.__exchangeRateToUSD, bytes) + else self.__exchangeRateToUSD + ), + ) + + class _subscriptionStatus: + class _account: + + _types_map = { + "isMinor": {"type": bool, "subtype": None}, + "suspectUnderage": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "isMinor": { + "required": True, + }, + "suspectUnderage": { + "required": True, + }, + } + + def __init__(self, isMinor: bool = None, suspectUnderage: bool = None): + pass + self.__isMinor = isMinor + self.__suspectUnderage = suspectUnderage + + def _get_isMinor(self): + return self.__isMinor + + def _set_isMinor(self, value): + if not isinstance(value, bool): + raise TypeError("isMinor must be bool") + + self.__isMinor = value + + isMinor = property(_get_isMinor, _set_isMinor) + + def _get_suspectUnderage(self): + return self.__suspectUnderage + + def _set_suspectUnderage(self, value): + if not isinstance(value, bool): + raise TypeError("suspectUnderage must be bool") + + self.__suspectUnderage = value + + suspectUnderage = property(_get_suspectUnderage, _set_suspectUnderage) + + @staticmethod + def from_dict(d): + v = {} + if "isMinor" in d: + v["isMinor"] = ( + bool.from_dict(d["isMinor"]) + if hasattr(bool, "from_dict") + else d["isMinor"] + ) + if "suspectUnderage" in d: + v["suspectUnderage"] = ( + bool.from_dict(d["suspectUnderage"]) + if hasattr(bool, "from_dict") + else d["suspectUnderage"] + ) + return StoreDownloadResp._subscriptionStatus._account(**v) + + def as_dict(self): + d = {} + if self.__isMinor is not None: + d["isMinor"] = ( + self.__isMinor.as_dict() + if hasattr(self.__isMinor, "as_dict") + else self.__isMinor + ) + if self.__suspectUnderage is not None: + d["suspectUnderage"] = ( + self.__suspectUnderage.as_dict() + if hasattr(self.__suspectUnderage, "as_dict") + else self.__suspectUnderage + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__isMinor[:20] + if isinstance(self.__isMinor, bytes) + else self.__isMinor + ), + limitedRepr( + self.__suspectUnderage[:20] + if isinstance(self.__suspectUnderage, bytes) + else self.__suspectUnderage + ), + ) + + class _terms: + + _types_map = { + "type": {"type": str, "subtype": None}, + "latestTerms": {"type": int, "subtype": None}, + "agreedToTerms": {"type": int, "subtype": None}, + "source": {"type": str, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "type": { + "required": True, + }, + "latestTerms": { + "required": True, + }, + "agreedToTerms": { + "required": True, + }, + "source": { + "required": True, + }, + } + + def __init__( + self, + type: str = None, + latestTerms: int = None, + agreedToTerms: int = None, + source: str = None, + ): + pass + self.__type = type + self.__latestTerms = latestTerms + self.__agreedToTerms = agreedToTerms + self.__source = source + + def _get_type(self): + return self.__type + + def _set_type(self, value): + if not isinstance(value, str): + raise TypeError("type must be str") + + self.__type = value + + type = property(_get_type, _set_type) + + def _get_latestTerms(self): + return self.__latestTerms + + def _set_latestTerms(self, value): + if not isinstance(value, int): + raise TypeError("latestTerms must be int") + + self.__latestTerms = value + + latestTerms = property(_get_latestTerms, _set_latestTerms) + + def _get_agreedToTerms(self): + return self.__agreedToTerms + + def _set_agreedToTerms(self, value): + if not isinstance(value, int): + raise TypeError("agreedToTerms must be int") + + self.__agreedToTerms = value + + agreedToTerms = property(_get_agreedToTerms, _set_agreedToTerms) + + def _get_source(self): + return self.__source + + def _set_source(self, value): + if not isinstance(value, str): + raise TypeError("source must be str") + + self.__source = value + + source = property(_get_source, _set_source) + + @staticmethod + def from_dict(d): + v = {} + if "type" in d: + v["type"] = ( + str.from_dict(d["type"]) + if hasattr(str, "from_dict") + else d["type"] + ) + if "latestTerms" in d: + v["latestTerms"] = ( + int.from_dict(d["latestTerms"]) + if hasattr(int, "from_dict") + else d["latestTerms"] + ) + if "agreedToTerms" in d: + v["agreedToTerms"] = ( + int.from_dict(d["agreedToTerms"]) + if hasattr(int, "from_dict") + else d["agreedToTerms"] + ) + if "source" in d: + v["source"] = ( + str.from_dict(d["source"]) + if hasattr(str, "from_dict") + else d["source"] + ) + return StoreDownloadResp._subscriptionStatus._terms(**v) + + def as_dict(self): + d = {} + if self.__type is not None: + d["type"] = ( + self.__type.as_dict() + if hasattr(self.__type, "as_dict") + else self.__type + ) + if self.__latestTerms is not None: + d["latestTerms"] = ( + self.__latestTerms.as_dict() + if hasattr(self.__latestTerms, "as_dict") + else self.__latestTerms + ) + if self.__agreedToTerms is not None: + d["agreedToTerms"] = ( + self.__agreedToTerms.as_dict() + if hasattr(self.__agreedToTerms, "as_dict") + else self.__agreedToTerms + ) + if self.__source is not None: + d["source"] = ( + self.__source.as_dict() + if hasattr(self.__source, "as_dict") + else self.__source + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__type[:20] + if isinstance(self.__type, bytes) + else self.__type + ), + limitedRepr( + self.__latestTerms[:20] + if isinstance(self.__latestTerms, bytes) + else self.__latestTerms + ), + limitedRepr( + self.__agreedToTerms[:20] + if isinstance(self.__agreedToTerms, bytes) + else self.__agreedToTerms + ), + limitedRepr( + self.__source[:20] + if isinstance(self.__source, bytes) + else self.__source + ), + ) + + class _family: + + _types_map = { + "hasFamily": {"type": bool, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "hasFamily": { + "required": True, + }, + } + + def __init__(self, hasFamily: bool = None): + pass + self.__hasFamily = hasFamily + + def _get_hasFamily(self): + return self.__hasFamily + + def _set_hasFamily(self, value): + if not isinstance(value, bool): + raise TypeError("hasFamily must be bool") + + self.__hasFamily = value + + hasFamily = property(_get_hasFamily, _set_hasFamily) + + @staticmethod + def from_dict(d): + v = {} + if "hasFamily" in d: + v["hasFamily"] = ( + bool.from_dict(d["hasFamily"]) + if hasattr(bool, "from_dict") + else d["hasFamily"] + ) + return StoreDownloadResp._subscriptionStatus._family(**v) + + def as_dict(self): + d = {} + if self.__hasFamily is not None: + d["hasFamily"] = ( + self.__hasFamily.as_dict() + if hasattr(self.__hasFamily, "as_dict") + else self.__hasFamily + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__hasFamily[:20] + if isinstance(self.__hasFamily, bytes) + else self.__hasFamily + ) + ) + + _types_map = { + "terms": {"type": list, "subtype": _terms}, + "account": {"type": _account, "subtype": None}, + "family": {"type": _family, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "terms": { + "required": True, + }, + "account": { + "required": True, + }, + "family": { + "required": True, + }, + } + + def __init__( + self, + terms: List[_terms] = None, + account: _account = None, + family: _family = None, + ): + pass + self.__terms = terms + self.__account = account + self.__family = family + + def _get_terms(self): + return self.__terms + + def _set_terms(self, value): + if not isinstance(value, list): + raise TypeError("terms must be list") + if not all( + isinstance(i, StoreDownloadResp._subscriptionStatus._terms) + for i in value + ): + raise TypeError( + "terms list values must be StoreDownloadResp._subscriptionStatus._terms" + ) + + self.__terms = value + + terms = property(_get_terms, _set_terms) + + def _get_account(self): + return self.__account + + def _set_account(self, value): + if not isinstance(value, StoreDownloadResp._subscriptionStatus._account): + raise TypeError( + "account must be StoreDownloadResp._subscriptionStatus._account" + ) + + self.__account = value + + account = property(_get_account, _set_account) + + def _get_family(self): + return self.__family + + def _set_family(self, value): + if not isinstance(value, StoreDownloadResp._subscriptionStatus._family): + raise TypeError( + "family must be StoreDownloadResp._subscriptionStatus._family" + ) + + self.__family = value + + family = property(_get_family, _set_family) + + @staticmethod + def from_dict(d): + v = {} + if "terms" in d: + v["terms"] = [ + StoreDownloadResp._subscriptionStatus._terms.from_dict(p) + if hasattr( + StoreDownloadResp._subscriptionStatus._terms, "from_dict" + ) + else p + for p in d["terms"] + ] + if "account" in d: + v["account"] = ( + StoreDownloadResp._subscriptionStatus._account.from_dict( + d["account"] + ) + if hasattr( + StoreDownloadResp._subscriptionStatus._account, "from_dict" + ) + else d["account"] + ) + if "family" in d: + v["family"] = ( + StoreDownloadResp._subscriptionStatus._family.from_dict(d["family"]) + if hasattr( + StoreDownloadResp._subscriptionStatus._family, "from_dict" + ) + else d["family"] + ) + return StoreDownloadResp._subscriptionStatus(**v) + + def as_dict(self): + d = {} + if self.__terms is not None: + d["terms"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__terms + ] + if self.__account is not None: + d["account"] = ( + self.__account.as_dict() + if hasattr(self.__account, "as_dict") + else self.__account + ) + if self.__family is not None: + d["family"] = ( + self.__family.as_dict() + if hasattr(self.__family, "as_dict") + else self.__family + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__terms[:20] + if isinstance(self.__terms, bytes) + else self.__terms + ), + limitedRepr( + self.__account[:20] + if isinstance(self.__account, bytes) + else self.__account + ), + limitedRepr( + self.__family[:20] + if isinstance(self.__family, bytes) + else self.__family + ), + ) + + _types_map = { + "pings": {"type": list, "subtype": float}, + "cancel_purchase_batch": {"type": bool, "subtype": None}, + "customerMessage": {"type": str, "subtype": None}, + "failureType": {"type": str, "subtype": None}, + "jingleDocType": {"type": str, "subtype": None}, + "jingleAction": {"type": str, "subtype": None}, + "status": {"type": int, "subtype": None}, + "dsPersonId": {"type": str, "subtype": None}, + "creditDisplay": {"type": str, "subtype": None}, + "creditBalance": {"type": str, "subtype": None}, + "freeSongBalance": {"type": str, "subtype": None}, + "authorized": {"type": bool, "subtype": None}, + "download_queue_item_count": {"type": int, "subtype": None}, + "songList": {"type": list, "subtype": _songList}, + "metrics": {"type": _metrics, "subtype": None}, + "subscriptionStatus": {"type": _subscriptionStatus, "subtype": None}, + } + _formats_map = {} + _validations_map = { + "pings": { + "required": True, + }, + "cancel_purchase_batch": { + "required": False, + }, + "customerMessage": { + "required": False, + }, + "failureType": { + "required": False, + }, + "jingleDocType": { + "required": True, + }, + "jingleAction": { + "required": True, + }, + "status": { + "required": True, + }, + "dsPersonId": { + "required": True, + }, + "creditDisplay": { + "required": True, + }, + "creditBalance": { + "required": True, + }, + "freeSongBalance": { + "required": True, + }, + "authorized": { + "required": True, + }, + "download_queue_item_count": { + "required": True, + }, + "songList": { + "required": True, + }, + "metrics": { + "required": True, + }, + "subscriptionStatus": { + "required": True, + }, + } + + def __init__( + self, + pings: List[float] = None, + cancel_purchase_batch: bool = None, + customerMessage: str = None, + failureType: str = None, + jingleDocType: str = None, + jingleAction: str = None, + status: int = None, + dsPersonId: str = None, + creditDisplay: str = None, + creditBalance: str = None, + freeSongBalance: str = None, + authorized: bool = None, + download_queue_item_count: int = None, + songList: List[_songList] = None, + metrics: _metrics = None, + subscriptionStatus: _subscriptionStatus = None, + ): + pass + self.__pings = pings + self.__cancel_purchase_batch = cancel_purchase_batch + self.__customerMessage = customerMessage + self.__failureType = failureType + self.__jingleDocType = jingleDocType + self.__jingleAction = jingleAction + self.__status = status + self.__dsPersonId = dsPersonId + self.__creditDisplay = creditDisplay + self.__creditBalance = creditBalance + self.__freeSongBalance = freeSongBalance + self.__authorized = authorized + self.__download_queue_item_count = download_queue_item_count + self.__songList = songList + self.__metrics = metrics + self.__subscriptionStatus = subscriptionStatus + + def _get_pings(self): + return self.__pings + + def _set_pings(self, value): + if not isinstance(value, list): + raise TypeError("pings must be list") + if not all(isinstance(i, float) for i in value): + raise TypeError("pings list values must be float") + + self.__pings = value + + pings = property(_get_pings, _set_pings) + + def _get_cancel_purchase_batch(self): + return self.__cancel_purchase_batch + + def _set_cancel_purchase_batch(self, value): + if value is not None and not isinstance(value, bool): + raise TypeError("cancel_purchase_batch must be bool") + + self.__cancel_purchase_batch = value + + cancel_purchase_batch = property( + _get_cancel_purchase_batch, _set_cancel_purchase_batch + ) + + def _get_customerMessage(self): + return self.__customerMessage + + def _set_customerMessage(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("customerMessage must be str") + + self.__customerMessage = value + + customerMessage = property(_get_customerMessage, _set_customerMessage) + + def _get_failureType(self): + return self.__failureType + + def _set_failureType(self, value): + if value is not None and not isinstance(value, str): + raise TypeError("failureType must be str") + + self.__failureType = value + + failureType = property(_get_failureType, _set_failureType) + + def _get_jingleDocType(self): + return self.__jingleDocType + + def _set_jingleDocType(self, value): + if not isinstance(value, str): + raise TypeError("jingleDocType must be str") + + self.__jingleDocType = value + + jingleDocType = property(_get_jingleDocType, _set_jingleDocType) + + def _get_jingleAction(self): + return self.__jingleAction + + def _set_jingleAction(self, value): + if not isinstance(value, str): + raise TypeError("jingleAction must be str") + + self.__jingleAction = value + + jingleAction = property(_get_jingleAction, _set_jingleAction) + + def _get_status(self): + return self.__status + + def _set_status(self, value): + if not isinstance(value, int): + raise TypeError("status must be int") + + self.__status = value + + status = property(_get_status, _set_status) + + def _get_dsPersonId(self): + return self.__dsPersonId + + def _set_dsPersonId(self, value): + if not isinstance(value, str): + raise TypeError("dsPersonId must be str") + + self.__dsPersonId = value + + dsPersonId = property(_get_dsPersonId, _set_dsPersonId) + + def _get_creditDisplay(self): + return self.__creditDisplay + + def _set_creditDisplay(self, value): + if not isinstance(value, str): + raise TypeError("creditDisplay must be str") + + self.__creditDisplay = value + + creditDisplay = property(_get_creditDisplay, _set_creditDisplay) + + def _get_creditBalance(self): + return self.__creditBalance + + def _set_creditBalance(self, value): + if not isinstance(value, str): + raise TypeError("creditBalance must be str") + + self.__creditBalance = value + + creditBalance = property(_get_creditBalance, _set_creditBalance) + + def _get_freeSongBalance(self): + return self.__freeSongBalance + + def _set_freeSongBalance(self, value): + if not isinstance(value, str): + raise TypeError("freeSongBalance must be str") + + self.__freeSongBalance = value + + freeSongBalance = property(_get_freeSongBalance, _set_freeSongBalance) + + def _get_authorized(self): + return self.__authorized + + def _set_authorized(self, value): + if not isinstance(value, bool): + raise TypeError("authorized must be bool") + + self.__authorized = value + + authorized = property(_get_authorized, _set_authorized) + + def _get_download_queue_item_count(self): + return self.__download_queue_item_count + + def _set_download_queue_item_count(self, value): + if not isinstance(value, int): + raise TypeError("download_queue_item_count must be int") + + self.__download_queue_item_count = value + + download_queue_item_count = property( + _get_download_queue_item_count, _set_download_queue_item_count + ) + + def _get_songList(self): + return self.__songList + + def _set_songList(self, value): + if not isinstance(value, list): + raise TypeError("songList must be list") + if not all(isinstance(i, StoreDownloadResp._songList) for i in value): + raise TypeError("songList list values must be StoreDownloadResp._songList") + + self.__songList = value + + songList = property(_get_songList, _set_songList) + + def _get_metrics(self): + return self.__metrics + + def _set_metrics(self, value): + if not isinstance(value, StoreDownloadResp._metrics): + raise TypeError("metrics must be StoreDownloadResp._metrics") + + self.__metrics = value + + metrics = property(_get_metrics, _set_metrics) + + def _get_subscriptionStatus(self): + return self.__subscriptionStatus + + def _set_subscriptionStatus(self, value): + if not isinstance(value, StoreDownloadResp._subscriptionStatus): + raise TypeError( + "subscriptionStatus must be StoreDownloadResp._subscriptionStatus" + ) + + self.__subscriptionStatus = value + + subscriptionStatus = property(_get_subscriptionStatus, _set_subscriptionStatus) + + @staticmethod + def from_dict(d): + v = {} + if "pings" in d: + v["pings"] = [ + float.from_dict(p) if hasattr(float, "from_dict") else p + for p in d["pings"] + ] + if "cancel-purchase-batch" in d: + v["cancel_purchase_batch"] = ( + bool.from_dict(d["cancel-purchase-batch"]) + if hasattr(bool, "from_dict") + else d["cancel-purchase-batch"] + ) + if "customerMessage" in d: + v["customerMessage"] = ( + str.from_dict(d["customerMessage"]) + if hasattr(str, "from_dict") + else d["customerMessage"] + ) + if "failureType" in d: + v["failureType"] = ( + str.from_dict(d["failureType"]) + if hasattr(str, "from_dict") + else d["failureType"] + ) + if "jingleDocType" in d: + v["jingleDocType"] = ( + str.from_dict(d["jingleDocType"]) + if hasattr(str, "from_dict") + else d["jingleDocType"] + ) + if "jingleAction" in d: + v["jingleAction"] = ( + str.from_dict(d["jingleAction"]) + if hasattr(str, "from_dict") + else d["jingleAction"] + ) + if "status" in d: + v["status"] = ( + int.from_dict(d["status"]) if hasattr(int, "from_dict") else d["status"] + ) + if "dsPersonId" in d: + v["dsPersonId"] = ( + str.from_dict(d["dsPersonId"]) + if hasattr(str, "from_dict") + else d["dsPersonId"] + ) + if "creditDisplay" in d: + v["creditDisplay"] = ( + str.from_dict(d["creditDisplay"]) + if hasattr(str, "from_dict") + else d["creditDisplay"] + ) + if "creditBalance" in d: + v["creditBalance"] = ( + str.from_dict(d["creditBalance"]) + if hasattr(str, "from_dict") + else d["creditBalance"] + ) + if "freeSongBalance" in d: + v["freeSongBalance"] = ( + str.from_dict(d["freeSongBalance"]) + if hasattr(str, "from_dict") + else d["freeSongBalance"] + ) + if "authorized" in d: + v["authorized"] = ( + bool.from_dict(d["authorized"]) + if hasattr(bool, "from_dict") + else d["authorized"] + ) + if "download-queue-item-count" in d: + v["download_queue_item_count"] = ( + int.from_dict(d["download-queue-item-count"]) + if hasattr(int, "from_dict") + else d["download-queue-item-count"] + ) + if "songList" in d: + v["songList"] = [ + StoreDownloadResp._songList.from_dict(p) + if hasattr(StoreDownloadResp._songList, "from_dict") + else p + for p in d["songList"] + ] + if "metrics" in d: + v["metrics"] = ( + StoreDownloadResp._metrics.from_dict(d["metrics"]) + if hasattr(StoreDownloadResp._metrics, "from_dict") + else d["metrics"] + ) + if "subscriptionStatus" in d: + v["subscriptionStatus"] = ( + StoreDownloadResp._subscriptionStatus.from_dict(d["subscriptionStatus"]) + if hasattr(StoreDownloadResp._subscriptionStatus, "from_dict") + else d["subscriptionStatus"] + ) + return StoreDownloadResp(**v) + + def as_dict(self): + d = {} + if self.__pings is not None: + d["pings"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__pings + ] + if self.__cancel_purchase_batch is not None: + d["cancel-purchase-batch"] = ( + self.__cancel_purchase_batch.as_dict() + if hasattr(self.__cancel_purchase_batch, "as_dict") + else self.__cancel_purchase_batch + ) + if self.__customerMessage is not None: + d["customerMessage"] = ( + self.__customerMessage.as_dict() + if hasattr(self.__customerMessage, "as_dict") + else self.__customerMessage + ) + if self.__failureType is not None: + d["failureType"] = ( + self.__failureType.as_dict() + if hasattr(self.__failureType, "as_dict") + else self.__failureType + ) + if self.__jingleDocType is not None: + d["jingleDocType"] = ( + self.__jingleDocType.as_dict() + if hasattr(self.__jingleDocType, "as_dict") + else self.__jingleDocType + ) + if self.__jingleAction is not None: + d["jingleAction"] = ( + self.__jingleAction.as_dict() + if hasattr(self.__jingleAction, "as_dict") + else self.__jingleAction + ) + if self.__status is not None: + d["status"] = ( + self.__status.as_dict() + if hasattr(self.__status, "as_dict") + else self.__status + ) + if self.__dsPersonId is not None: + d["dsPersonId"] = ( + self.__dsPersonId.as_dict() + if hasattr(self.__dsPersonId, "as_dict") + else self.__dsPersonId + ) + if self.__creditDisplay is not None: + d["creditDisplay"] = ( + self.__creditDisplay.as_dict() + if hasattr(self.__creditDisplay, "as_dict") + else self.__creditDisplay + ) + if self.__creditBalance is not None: + d["creditBalance"] = ( + self.__creditBalance.as_dict() + if hasattr(self.__creditBalance, "as_dict") + else self.__creditBalance + ) + if self.__freeSongBalance is not None: + d["freeSongBalance"] = ( + self.__freeSongBalance.as_dict() + if hasattr(self.__freeSongBalance, "as_dict") + else self.__freeSongBalance + ) + if self.__authorized is not None: + d["authorized"] = ( + self.__authorized.as_dict() + if hasattr(self.__authorized, "as_dict") + else self.__authorized + ) + if self.__download_queue_item_count is not None: + d["download-queue-item-count"] = ( + self.__download_queue_item_count.as_dict() + if hasattr(self.__download_queue_item_count, "as_dict") + else self.__download_queue_item_count + ) + if self.__songList is not None: + d["songList"] = [ + p.as_dict() if hasattr(p, "as_dict") else p for p in self.__songList + ] + if self.__metrics is not None: + d["metrics"] = ( + self.__metrics.as_dict() + if hasattr(self.__metrics, "as_dict") + else self.__metrics + ) + if self.__subscriptionStatus is not None: + d["subscriptionStatus"] = ( + self.__subscriptionStatus.as_dict() + if hasattr(self.__subscriptionStatus, "as_dict") + else self.__subscriptionStatus + ) + return d + + def __repr__(self): + return "".format( + limitedRepr( + self.__pings[:20] if isinstance(self.__pings, bytes) else self.__pings + ), + limitedRepr( + self.__cancel_purchase_batch[:20] + if isinstance(self.__cancel_purchase_batch, bytes) + else self.__cancel_purchase_batch + ), + limitedRepr( + self.__customerMessage[:20] + if isinstance(self.__customerMessage, bytes) + else self.__customerMessage + ), + limitedRepr( + self.__failureType[:20] + if isinstance(self.__failureType, bytes) + else self.__failureType + ), + limitedRepr( + self.__jingleDocType[:20] + if isinstance(self.__jingleDocType, bytes) + else self.__jingleDocType + ), + limitedRepr( + self.__jingleAction[:20] + if isinstance(self.__jingleAction, bytes) + else self.__jingleAction + ), + limitedRepr( + self.__status[:20] + if isinstance(self.__status, bytes) + else self.__status + ), + limitedRepr( + self.__dsPersonId[:20] + if isinstance(self.__dsPersonId, bytes) + else self.__dsPersonId + ), + limitedRepr( + self.__creditDisplay[:20] + if isinstance(self.__creditDisplay, bytes) + else self.__creditDisplay + ), + limitedRepr( + self.__creditBalance[:20] + if isinstance(self.__creditBalance, bytes) + else self.__creditBalance + ), + limitedRepr( + self.__freeSongBalance[:20] + if isinstance(self.__freeSongBalance, bytes) + else self.__freeSongBalance + ), + limitedRepr( + self.__authorized[:20] + if isinstance(self.__authorized, bytes) + else self.__authorized + ), + limitedRepr( + self.__download_queue_item_count[:20] + if isinstance(self.__download_queue_item_count, bytes) + else self.__download_queue_item_count + ), + limitedRepr( + self.__songList[:20] + if isinstance(self.__songList, bytes) + else self.__songList + ), + limitedRepr( + self.__metrics[:20] + if isinstance(self.__metrics, bytes) + else self.__metrics + ), + limitedRepr( + self.__subscriptionStatus[:20] + if isinstance(self.__subscriptionStatus, bytes) + else self.__subscriptionStatus + ), + ) diff --git a/src_mac/ipatool-py/reqs/store.py b/src_mac/ipatool-py/reqs/store.py new file mode 100755 index 0000000..ede8c53 --- /dev/null +++ b/src_mac/ipatool-py/reqs/store.py @@ -0,0 +1,254 @@ +import hashlib +import json +import pickle +import plistlib +import requests +from reqs.schemas.store_authenticate_req import StoreAuthenticateReq +from reqs.schemas.store_authenticate_resp import StoreAuthenticateResp +from reqs.schemas.store_buyproduct_req import StoreBuyproductReq +from reqs.schemas.store_buyproduct_resp import StoreBuyproductResp +from reqs.schemas.store_download_req import StoreDownloadReq +from reqs.schemas.store_download_resp import StoreDownloadResp + +class StoreException(Exception): + def __init__(self, req, resp, errMsg, errType=None): + self.req = req + self.resp = resp # type: StoreDownloadResp + self.errMsg = errMsg + self.errType = errType + super().__init__( + "Store %s error: %s" % (self.req, self.errMsg) if not self.errType else + "Store %s error: %s, errorType: %s" % (self.req, self.errMsg, self.errType) + ) + +#CONFIGURATOR_UA = "Configurator/2.0 (Macintosh; OS X 10.12.6; 16G29) AppleWebKit/2603.3.8" +CONFIGURATOR_UA = 'Configurator/2.0 (Macintosh; OS X 10.12.6; 16G29) AppleWebKit/2603.3.8 iOS/14.2 hwp/t8020' + +class StoreClientAuth(object): + def __init__(self, appleId=None, password=None): + self.appleId = appleId + self.password = password + self.guid = None # the guid will not be used in itunes server mode + self.accountName = None + self.authHeaders = None + self.authCookies = None + + def __str__(self): + return f"<{self.accountName} [{self.guid}]>" + + def _generateGuid(self, appleId): + ''' + Derive a GUID for an appleId. For each appleId, the GUID will always remain the same + :param appleId: + :return: + ''' + DEFAULT_GUID = '000C2941396B' # this GUID is blocked + # number of chars to use from DEFAULT_GUID as prefix (0..12) + GUID_DEFAULT_PREFIX = 2 + # something unique + GUID_SEED = 'CAFEBABE' + # something between 0 and 30 + GUID_POS = 10 + + # generate a unique guid out of the appleId + h = hashlib.sha1((GUID_SEED + appleId + GUID_SEED).encode("utf-8")).hexdigest() + defaultPart = DEFAULT_GUID[:GUID_DEFAULT_PREFIX] + hashPart = h[GUID_POS: GUID_POS + (len(DEFAULT_GUID) - GUID_DEFAULT_PREFIX)] + guid = (defaultPart + hashPart).upper() + return guid + + def login(self, sess): + if not self.guid: + self.guid = self._generateGuid(self.appleId) + + req = StoreAuthenticateReq(appleId=self.appleId, password=self.password, attempt='4', createSession="true", + guid=self.guid, rmp='0', why='signIn') + url = "https://p46-buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/authenticate?guid=%s" % self.guid + while True: + r = sess.post(url, + headers={ + "Accept": "*/*", + "Content-Type": "application/x-www-form-urlencoded", + "User-Agent": CONFIGURATOR_UA, + }, data=plistlib.dumps(req.as_dict()), allow_redirects=False) + if r.status_code == 302: + url = r.headers['Location'] + continue + break + d = plistlib.loads(r.content) + resp = StoreAuthenticateResp.from_dict(d) + if not resp.m_allowed: + raise StoreException("authenticate", d, resp.customerMessage, resp.failureType) + + self.authHeaders = {} + self.authHeaders['X-Dsid'] = self.authHeaders['iCloud-Dsid'] = str(resp.download_queue_info.dsid) + self.authHeaders['X-Apple-Store-Front'] = r.headers.get('x-set-apple-store-front') + self.authHeaders['X-Token'] = resp.passwordToken + self.authCookies = pickle.dumps(sess.cookies).hex() + + self.accountName = resp.accountInfo.address.firstName + " " + resp.accountInfo.address.lastName + def save(self): + return json.dumps(self.__dict__) + + @classmethod + def load(cls, j): + obj = json.loads(j) + ret = cls() + ret.__dict__.update(obj) + return ret + +class StoreClient(object): + def __init__(self, sess: requests.Session): + self.sess = sess + self.iTunes_provider = None + self.authInfo = None + + def authenticate_load_session(self, sessionContent): + self.authInfo = StoreClientAuth.load(sessionContent) + if self.authInfo.authHeaders is None or self.authInfo.authCookies is None: + raise Exception("invalid auth session") + self.sess.headers = dict(self.authInfo.authHeaders) + self.sess.cookies = pickle.loads(bytes.fromhex(self.authInfo.authCookies)) + + def authenticate_save_session(self): + return self.authInfo.save() + + def authenticate(self, appleId, password): + if not self.authInfo: + self.authInfo = StoreClientAuth(appleId, password) + self.authInfo.login(self.sess) + self.sess.headers = dict(self.authInfo.authHeaders) + self.sess.cookies = pickle.loads(bytes.fromhex(self.authInfo.authCookies)) + + # ==> 🛠 [Verbose] Performing request: curl -k -X POST \ + # -H "iCloud-DSID: 12263680861" \ + # -H "Content-Type: application/x-www-form-urlencoded" \ + # -H "User-Agent: Configurator/2.0 (Macintosh; OS X 10.12.6; 16G29) AppleWebKit/2603.3.8" \ + # -H "X-Dsid: 12263680861" \ + # -d ' + # + # + # + # creditDisplay + # + # guid + # 000C2941396B + # salableAdamId + # 1239860606 + # + # + # ' \ + # https://p25-buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/volumeStoreDownloadProduct?guid=000C2941396Bk + def volumeStoreDownloadProduct(self, appId, appVerId=""): + req = StoreDownloadReq(creditDisplay="", guid=self.authInfo.guid, salableAdamId=appId, appExtVrsId=appVerId) + hdrs = { + "Content-Type": "application/x-www-form-urlencoded", + "User-Agent": CONFIGURATOR_UA, + } + url = "https://p25-buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/volumeStoreDownloadProduct?guid=%s" % self.authInfo.guid + payload = req.as_dict() + r = self.sess.post(url, + headers=hdrs, + data=plistlib.dumps(payload)) + d = plistlib.loads(r.content) + resp = StoreDownloadResp.from_dict(d) + if resp.cancel_purchase_batch: + raise StoreException("volumeStoreDownloadProduct", d, resp.customerMessage, '%s-%s' % (resp.failureType, resp.metrics)) + return resp + + def buyProduct(self, appId, appVer='', productType='C', pricingParameters='STDQ'): + # STDQ - buy, STDRDL - redownload, SWUPD - update + url = "https://p25-buy.itunes.apple.com/WebObjects/MZBuy.woa/wa/buyProduct" + + itunes_internal = self.iTunes_provider(url) + hdrs = itunes_internal.pop('headers') + guid = itunes_internal.pop('guid') + kbsync = itunes_internal.pop('kbsync') + + if not appVer: + from reqs.itunes import iTunesClient + iTunes = iTunesClient(self.sess) + appVer = iTunes.getAppVerId(appId, hdrs['X-Apple-Store-Front']) + + req = StoreBuyproductReq( + guid=guid, + salableAdamId=str(appId), + appExtVrsId=str(appVer) if appVer else None, + + price='0', + productType=productType, + pricingParameters=pricingParameters, + + ageCheck='true', + hasBeenAuthedForBuy='true', + isInApp='false', + hasConfirmedPaymentSheet='true', + asn='1', + ) + payload = req.as_dict() + payload['kbsync'] = kbsync # kbsync is bytes, but json schema does not support it, so we have to assign it + if 'sbsync' in itunes_internal: + payload['sbsync'] = itunes_internal.pop('sbsync') # sbsync is the same as kbsync + if 'afds' in itunes_internal: + payload['afds'] = itunes_internal.pop('afds') + + hdrs = dict(hdrs) + hdrs["Content-Type"] = "application/x-apple-plist" + + r = self.sess.post(url, + headers=hdrs, + data=plistlib.dumps(payload) + ) + + d = plistlib.loads(r.content) + resp = StoreBuyproductResp.from_dict(d) + if resp.cancel_purchase_batch: + raise StoreException("buyProduct", d, resp.customerMessage, '%s-%s' % (resp.failureType, resp.metrics)) + return resp + + def buyProduct_purchase(self, appId, productType='C'): + url = "https://buy.itunes.apple.com/WebObjects/MZBuy.woa/wa/buyProduct" + req = StoreBuyproductReq( + guid=self.authInfo.guid, + salableAdamId=str(appId), + appExtVrsId='0', + + price='0', + productType=productType, + pricingParameters='STDQ', + + hasAskedToFulfillPreorder='true', + buyWithoutAuthorization='true', + hasDoneAgeCheck='true', + hasConfirmedPaymentSheet='true', + ) + payload = req.as_dict() + + r = self.sess.post(url, + headers={ + "Content-Type": "application/x-apple-plist", + "User-Agent": "Configurator/2.15 (Macintosh; OS X 11.0.0; 16G29) AppleWebKit/2603.3.8", + }, + data=plistlib.dumps(payload)) + + if r.status_code == 500: + raise StoreException("buyProduct_purchase", None, 'purchased_before') + + d = plistlib.loads(r.content) + resp = StoreBuyproductResp.from_dict(d) + if resp.status != 0 or resp.jingleDocType != 'purchaseSuccess': + raise StoreException("buyProduct_purchase", d, resp.customerMessage, + '%s-%s' % (resp.status, resp.jingleDocType)) + return resp + + def purchase(self, appId): + if self.iTunes_provider: + return None # iTunes mode will automatically purchase the app if not purchased + else: + return self.buyProduct_purchase(appId) + + def download(self, appId, appVer='', isRedownload=True): + if self.iTunes_provider: + return self.buyProduct(appId, appVer, pricingParameters='STDRDL' if isRedownload else 'STDQ') + else: + return self.volumeStoreDownloadProduct(appId, appVer) \ No newline at end of file diff --git a/src_mac/ipatool-py/requirements.txt b/src_mac/ipatool-py/requirements.txt new file mode 100755 index 0000000..fa1aea2 --- /dev/null +++ b/src_mac/ipatool-py/requirements.txt @@ -0,0 +1,2 @@ +rich>=10.2.2 +requests>=2.25.0 diff --git a/src_mac/lib.py b/src_mac/lib.py new file mode 100755 index 0000000..32e37f2 --- /dev/null +++ b/src_mac/lib.py @@ -0,0 +1,269 @@ +#!/usr/bin/env python3 +from pathlib import Path +from subprocess import run +from typing import Dict, NamedTuple +from zipfile import ZipFile +import json +import os +import plistlib +import shutil + +from cfg import CONFIG, Log + + +# ------------------------------ +# Types +# ------------------------------ + + +VersionMap = Dict[int, str] + + +class FlatVersion(NamedTuple): + verId: int + verOs: int + + +class InfoPlist(NamedTuple): + appId: int + verId: int + allVersions: 'list[int]' + bundleId: str + osVer: str + + +class LocalIpaFile(NamedTuple): + cracked: bool + path: Path + + +# ------------------------------ +# IPA tool +# ------------------------------ + +def ipaTool(*args: 'str|Path') -> None: + # '--json' + run(['python3', Path(__file__).parent/'ipatool-py'/'main.py'] + list(args)) + + +def ipaToolHistory(appId: int): + Log.info('history for appid=%d', appId) + ipaTool('historyver', '-s', CONFIG.itunes_server, + '-o', CONFIG.download_tmp, '-i', str(appId)) + + +def ipaToolDownload(appId: int, verId: int): + Log.info('download appid=%d verid=%d', appId, verId) + ipaTool('download', '-s', CONFIG.itunes_server, '-o', CONFIG.download_tmp, + '-i', str(appId), '--appVerId', str(verId)) + + +# ------------------------------ +# Path handling +# ------------------------------ + +def pathForApp(appId: int) -> 'Path|None': + return next(CONFIG.completed.glob(f'* - {appId}/'), None) + + +def pathForIpa(appId: int, appVerId: int) -> 'Path|None': + app_path = pathForApp(appId) + if not app_path: + return None + return next(app_path.glob(f'* - {appVerId}.ipa'), None) + + +# ------------------------------ +# IPA content reading +# ------------------------------ + +def ipaReadInfoPlist(fname: Path) -> InfoPlist: + with ZipFile(fname) as zip: + itunesPlist = plistlib.loads(zip.read('iTunesMetadata.plist')) + for entry in zip.filelist: + p = entry.filename.split('/') + if len(p) == 3 and p[0] == 'Payload' and p[2] == 'Info.plist': + infoPlist = plistlib.loads(zip.read(entry)) + break + return InfoPlist( + itunesPlist['itemId'], + itunesPlist['softwareVersionExternalIdentifier'], + itunesPlist['softwareVersionExternalIdentifiers'], + # itunesPlist['softwareVersionBundleId'] + infoPlist['CFBundleIdentifier'], + infoPlist.get('MinimumOSVersion', '1.0'), + ) + + +# ------------------------------ +# Version Map +# ------------------------------ + +def readVersionMap(appId: int) -> 'VersionMap|None': + app_dir = pathForApp(appId) + if app_dir: + ver_map_json = app_dir / '_versions.json' + if ver_map_json.exists(): + with open(ver_map_json, 'rb') as fp: + data: dict[str, str] = json.load(fp) + return {int(k): v for k, v in data.items()} + return None + + +def readVersionMapFromTemp(appId: int) -> 'VersionMap|None': + hist_json = CONFIG.download_tmp / f'historyver_{appId}.json' + if hist_json.exists(): + with open(hist_json, 'rb') as fp: + allVerIds: list[int] = json.load(fp)['appVerIds'] + return {x: '' for x in allVerIds} + return None + + +def writeVersionMap(appId: int, data: VersionMap): + app_dir = pathForApp(appId) + assert app_dir, f'app dir must exist for {appId} before calling this.' + + with open(app_dir / '_versions.json', 'w') as fp: + json.dump(data, fp, indent=2, sort_keys=True) + + hist_json = CONFIG.download_tmp / f'historyver_{appId}.json' + if hist_json.exists(): + os.remove(hist_json) + + +def updateVersionMap(fname: Path) -> InfoPlist: + ''' Returns iOS version string ''' + info = ipaReadInfoPlist(fname) + if not pathForApp(info.appId): + app_dir = CONFIG.completed / f'{info.bundleId} - {info.appId}' + app_dir.mkdir(parents=True, exist_ok=True) + data = readVersionMap(info.appId) + if not data: + data = readVersionMapFromTemp(info.appId) + if not data: + data: 'VersionMap|None' = {x: '' for x in info.allVersions} + + assert data, f'by now, history json for {info.appId} should exist!' + + if data.get(info.verId) != info.osVer: + for x in info.allVersions: + if x not in data: + data[x] = '' + data[info.verId] = info.osVer + Log.info('update version for %s (%s)', info.appId, info.bundleId) + writeVersionMap(info.appId, data) + return info + + +def flattenVersionMap(data: VersionMap) -> 'list[FlatVersion]': + return sorted(FlatVersion(k, versionToInt(v)) for k, v in data.items()) + + +def loadFlatVersionMap(appId: int) -> 'list[FlatVersion]': + data = readVersionMap(appId) + if not data: + data = readVersionMapFromTemp(appId) + if not data: # needs download + ipaToolHistory(appId) + data = readVersionMapFromTemp(appId) + if not data: + raise RuntimeError(f'could not download version history for {appId}') + return flattenVersionMap(data) + + +# ------------------------------ +# Helper +# ------------------------------ + +def versionToInt(ver: str) -> int: + if not ver: + return 0 + major, minor, patch, *_ = ver.split('.') + [0, 0, 0] + return int(major) * 1_00_00 + int(minor) * 1_00 + int(patch) + + +def enumAppIds(): + return sorted([int(x.parent.name.split(' ')[-1]) + for x in CONFIG.completed.glob('*/_versions.json')]) + + +def downloadPath(appId: int, verId: int): + return CONFIG.download_fix / f'{appId}.{verId}.ipa' + + +# ------------------------------ +# Actual logic +# ------------------------------ + +def downloadSpecificVersion(appId: int, verId: int) -> LocalIpaFile: + ipa_path = pathForIpa(appId, verId) + if ipa_path: + return LocalIpaFile(True, ipa_path) # already cracked + + download_path = downloadPath(appId, verId) + if download_path.exists(): + return LocalIpaFile(False, download_path) # needs cracking + + ipaToolDownload(appId, verId) + tmp_file = next(CONFIG.download_tmp.glob(f'*-{appId}-{verId}.ipa'), None) + if not tmp_file: + raise RuntimeError(f'Could not download ipa {appId} {verId}') + + shutil.move(tmp_file.as_posix(), download_path) + updateVersionMap(download_path) + return LocalIpaFile(False, download_path) + + +def findLatestVersion( + appId: int, maxOS: str, *, rmIncompatible: bool +) -> 'int|None': + ver_map = loadFlatVersionMap(appId) + _maxOS = versionToInt(maxOS) + + def proc_index(i: int) -> bool: + verId, osVer = ver_map[i] + if not osVer: + ipa_file = downloadSpecificVersion(appId, verId) + info = ipaReadInfoPlist(ipa_file.path) + osVer = versionToInt(info.osVer) + if rmIncompatible and osVer > _maxOS and not ipa_file.cracked: + os.remove(ipa_file.path) + Log.debug('app: %d ver: %d iOS: %s ...', appId, verId, osVer) + return osVer <= _maxOS + + if not proc_index(0): + Log.warning(f'No compatible version for {appId}') + return None + + imin, imax = 1, len(ver_map) - 1 + best_i = 0 + while imin <= imax: + i = imin + (imax - imin) // 2 + if proc_index(i): + best_i = i + imin = i + 1 + else: + best_i = i - 1 + imax = i - 1 + return ver_map[best_i].verId + + +def downloadAllUntil( + idx: int, appId: int, maxOS: str, *, rmIncompatible: bool +) -> 'Path|None': + ver_map = loadFlatVersionMap(appId) + _maxOS = versionToInt(maxOS) + if idx >= len(ver_map): + return None + if any(x.verOs > _maxOS for x in ver_map[:idx + 1]): + return None + verId = ver_map[idx].verId + ipa_file = downloadSpecificVersion(appId, verId) + if ipa_file.cracked: + return None + info = ipaReadInfoPlist(ipa_file.path) + osVer = versionToInt(info.osVer) + if osVer <= _maxOS: + return ipa_file.path + elif rmIncompatible: + os.remove(ipa_file.path) diff --git a/src_mac/move_em.py b/src_mac/move_em.py new file mode 100755 index 0000000..63a41d3 --- /dev/null +++ b/src_mac/move_em.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 +from pathlib import Path +import os +import shutil + +from cfg import CONFIG, Log +from lib import ipaReadInfoPlist +from server import WinServer + + +def moveEmAll(): + for fname in CONFIG.sync_in.glob('*.ipa'): + info = ipaReadInfoPlist(Path(fname)) + FROM = Path(fname) + new_name = FROM.name[:-4] + f' - {info.verId}.ipa' + DEST = next(CONFIG.completed.glob(f'{info.bundleId} */')) / new_name + Log.info('[mv] -> %s', DEST.name) + shutil.move(FROM.as_posix(), DEST) + + # cleanup download files + orig_filename = f'{info.appId}.{info.verId}.ipa' + download_file = CONFIG.download_fix / orig_filename + if download_file.exists(): + Log.info('[delete] %s', download_file) + os.remove(download_file) + + Log.info('[uninstall] %s', info.bundleId) + WinServer.uninstall(info.bundleId) + + +if __name__ == '__main__': + moveEmAll() diff --git a/src_mac/repack_ipa.py b/src_mac/repack_ipa.py new file mode 100755 index 0000000..c05065c --- /dev/null +++ b/src_mac/repack_ipa.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 +from argparse import ArgumentParser +from pathlib import Path +from subprocess import run +from zipfile import ZipFile +import os +import re +import shutil + +from cfg import CONFIG, Log + +_rx_coh = re.compile(r'\s*storeCohort<\/key>\s*[^<]*<\/string>') + + +def cleanupZipDir(path: Path): + if (path / 'IPAToolInfo.plist').exists(): + os.remove(path / 'IPAToolInfo.plist') + shutil.rmtree(path / 'META-INF', ignore_errors=True) + + if CONFIG.convert_plist: + ii = next((path / 'Payload').glob('*.app')) / 'Info.plist' + run(f'/usr/libexec/PlistBuddy -x -c print {ii} > {ii}.tmp', shell=True) + os.remove(ii) + os.rename(f'{ii}.tmp', ii) + + with open(path / 'iTunesMetadata.plist', 'r') as fp: + data = fp.read() + start, end = _rx_coh.search(data).span() # type: ignore assume exist + with open(path / 'iTunesMetadata.plist', 'w') as fp: + fp.write(data[:start]) + fp.write(data[end:]) + + +def repackIpa(ipa_path: Path): + is_dir = ipa_path.is_dir() and (ipa_path / 'IPAToolInfo.plist').exists() + tmp_unzip_dir = ipa_path if is_dir else Path('tmp_unzip') + + target_path = CONFIG.sync_out / ipa_path.name + if is_dir: # in case of manual extraction (needed for utf8 filenames) + just_app_ver_id = target_path.name.split(' ', 1)[0] # " 2" or " copy" + target_path = target_path.with_name(just_app_ver_id + '.ipa') + if target_path.exists(): + return + + if ipa_path.is_file(): + Log.info('[unzip] %s', ipa_path) + shutil.rmtree(tmp_unzip_dir, ignore_errors=True) + tmp_unzip_dir.mkdir(exist_ok=True) + + with ZipFile(ipa_path) as zip: + zip.extractall(tmp_unzip_dir) + else: + Log.info('[repack-dir] %s', ipa_path) + + cleanupZipDir(tmp_unzip_dir) + + Log.info('[zip] %s', target_path) + shutil.make_archive(str(target_path), 'zip', str(tmp_unzip_dir)) + shutil.move(str(target_path) + '.zip', str(target_path)) + shutil.rmtree(tmp_unzip_dir, ignore_errors=True) + + +if __name__ == '__main__': + cli = ArgumentParser() + cli.add_argument('ipa', type=Path, nargs='+') + args = cli.parse_args() + + for fname in args.ipa: + repackIpa(fname) diff --git a/src_mac/server.py b/src_mac/server.py new file mode 100755 index 0000000..b71329e --- /dev/null +++ b/src_mac/server.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +from pathlib import Path +from urllib.request import urlopen + +from cfg import CONFIG, Log + + +class WinApiServer(): + def __init__(self) -> None: + self.server_url = CONFIG.win_server + if self._post('up', '') != 'YES': + raise RuntimeError( + f'WinServer {self.server_url} does not seem to be running') + + def _post(self, action: str, data: str) -> str: + ''' With 10min timeout ''' + url = f'{self.server_url}/{action}' + Log.debug('POST %s --data %s', url, data) + with urlopen(url, data=data.encode('utf8'), timeout=1200) as fp: + return fp.read().decode('utf8') + + def install(self, fname: Path) -> str: + if fname.suffix != '.ipa': + raise ValueError(f'Not an *.ipa file: "{fname}"') + if not fname.exists() or fname.is_dir(): + raise ValueError(f'File not found: "{fname}"') + if fname.absolute().parent != CONFIG.sync_out.absolute(): + raise ValueError(f'Install file not in SYNC OUT dir: "{fname}"') + return self._post('install', fname.name) + + def uninstall(self, bundleId: str) -> str: + return self._post('uninstall', bundleId) + + +WinServer = WinApiServer() diff --git a/src_win/actions-iTunes-header/action.yml b/src_win/actions-iTunes-header/action.yml new file mode 100755 index 0000000..d1adfa2 --- /dev/null +++ b/src_win/actions-iTunes-header/action.yml @@ -0,0 +1,92 @@ +name: 'Get iTunes Headers & Kbsync' +inputs: + apple_id: + required: true + apple_id_pwd: + required: true + ngrok_token: + description: "Token for RDP debugging" + required: false + +runs: + using: "composite" + steps: + - name: Check if initialized + id: check + run: | + echo "Checking if we need to initialize iTunes again" + if [[ "$(cat /c/.iTunesInitialized)" == "${{ inputs.ngrok-token }}" ]]; then + echo " Need to re-init iTunes" + echo "NEED_INIT=1" >> $GITHUB_ENV + else + echo " Needn't to do anything" + echo "NEED_INIT=0" >> $GITHUB_ENV + fi + working-directory: ${{ github.action_path }} + shell: bash + - name: Setup iTunes + if: ${{ env.NEED_INIT == 1 }} + run: | + echo Setup iTunes... + start /wait taskkill /f /im iTunes* python* + workflow_helper\iTunesInstall\install_itunes.bat + working-directory: ${{ github.action_path }} + shell: cmd + + - name: Setup Python Dependencies + if: ${{ env.NEED_INIT == 1 }} + run: | + echo Setup Python Dependencies... + pip3 install pywinauto frida Flask + working-directory: ${{ github.action_path }} + shell: cmd + + #- uses: NyaMisty/reverse-rdp-windows-github-actions-ng@master + # if: ${{ always() && github.event_name == 'workflow_dispatch' && github.event.inputs.itunes_debug_enabled }} + # with: + # ngrok-token: ${{ inputs.ngrok_token }} + # password: Aa123456 + # foreground: false + + - name: Login iTunes + if: ${{ env.NEED_INIT == 1 }} + env: + APPLEID: ${{ inputs.apple_id }} + APPLEID_PWD: ${{ inputs.apple_id_pwd }} + run: | + echo Login iTunes... + python3 workflow_helper/itunes_auto_login.py %APPLEID% %APPLEID_PWD% + working-directory: ${{ github.action_path }} + shell: cmd + + - name: Finish Initialization + if: ${{ env.NEED_INIT == 1 }} + env: + APPLEID: ${{ inputs.apple_id }} + run: | + echo "Finish Initialization..." + echo "$APPLEID" > /c/.iTunesInitialized + working-directory: ${{ github.action_path }} + shell: bash + + - name: Start Frida Header Server + run: | + echo Start Frida Header Server! + curl -Lo psexec64.exe https://github.com/ComputerGuyYash/psexec/raw/main/PsExec64.exe + psexec64.exe -accepteula -nobanner -i -d cmd /c "python3.exe workflow_helper/iTunesDownload/get_header.py > C:\get_header.log 2>&1" + exit 0 + working-directory: ${{ github.action_path }} + shell: cmd + + - name: Test Frida Header Server + run: | + sleep 5 + ret=0 + echo "---------------- Before query headers ----------------" + cat /c/get_header.log + curl --fail-with-body -vv 127.0.0.1:9000 || ret=$? + echo "---------------- After query headers ----------------" + cat /c/get_header.log + exit $ret + working-directory: ${{ github.action_path }} + shell: bash diff --git a/src_win/actions-iTunes-header/patch_itunes.py b/src_win/actions-iTunes-header/patch_itunes.py new file mode 100755 index 0000000..fddcc6b --- /dev/null +++ b/src_win/actions-iTunes-header/patch_itunes.py @@ -0,0 +1,22 @@ +import os + +# for debug +P = r"C:\Program Files\iTunes\iTunes1.exe" +if not os.path.exists(P): + # for production + P = r"C:\Program Files\iTunes\iTunes.exe" + +with open(P, 'rb') as f: + data = f.read() + +data = bytearray(data) + +# Patch passwordSettings (actually useless) +data[0x77daf4:0x77daf4+5] = b'\xBF\x03\x00\x00\x00' +data[0x77db7e:0x77db7e+2] = b'\xEB\x0A' + +# Patch signIn reason to serverDialog +data[0x7a9ed4:0x7a9ed4+6] = b'\xB9\x23\xFF\xFF\xFF\x90' + +with open(P, 'wb') as f: + f.write(data) \ No newline at end of file diff --git a/src_win/actions-iTunes-header/workflow_helper/iTunesDownload/get_header.py b/src_win/actions-iTunes-header/workflow_helper/iTunesDownload/get_header.py new file mode 100755 index 0000000..bb1eb7c --- /dev/null +++ b/src_win/actions-iTunes-header/workflow_helper/iTunesDownload/get_header.py @@ -0,0 +1,113 @@ +# frida_rpc_player.py + +''' +POST /WebObjects/MZBuy.woa/wa/buyProduct HTTP/1.1 +Host: p46-buy.itunes.apple.com +User-Agent: iTunes/12.6.5 (Windows; Microsoft Windows 10.0 x64 Enterprise Edition (Build 19042); x64) AppleWebKit/7605.1033.1002.2 +Content-Length: 1226 +Content-Type: application/x-apple-plist +X-Dsid: 12263680861 +X-Apple-Tz: 28800 +X-Apple-MD: AAAABAAAABA3hIN/KYf4Ri4tdZAiwaB5 +Cookie: amp=JG7EpvImu+/h0yS5mTqQMLarQce6xuYNfyzC6cun/bRt+7VLQUqfUrDB4cdRyV6SLDGBRCG3Oz/PcY28nx94GdTGkdOYX83a54KHZTSq3jI=; amia-12263680861=dPQK5oK/9b6q7HeGIids4a6gE5oiE8yLcVjQO7EknSTERhI0OawL4FQcmJ60560H+PbZhCCt6Na8jLSDiU09aw==; mt-asn-12263680861=2; mt-tkn-12263680861=AmDauzfLChTup9vGq17bGVJvSurhbsyoCLyrpJG8t8uECuyAI3xr3o/vS9pVpKeg4dSlCxJtLUS8+H47Qtpou0VGgGBAn/dXAPozhdJKTyPdUqyT4My89dujXg48XNgIVUjFj2w4IhN1gg5wn3BfSg1bFChodxuHadsRibnYzkUPmR+TVTnivu9e4/QLJmh58Va8rmg=; mt-tkn-10255130069=Ala2nKdNzZWOlapGgvRzcNExINc8j4sbrcMn3ruJ9M3Cb17MGiGqvyTe9yUzh/fSNLEL+4s0j57Eht/AWXrG2e3+GptHZlTi1vZ4a+3PdD9dtfSP8no7s9/bMX6JTtnE+fwV1z8QudsvAs+kjEz0MqFgoxFZZntBKI1L81+CBTnmsBolRdk+wqqPGZ3AD5bdybUTwD4=; countryVerified=1; mzf_in=467080; itspod=46; vrep=CN3W49ctEgQIChAAEgQICBAAEgQIBxAAEgQIBBAAEgQIDRAAEgQIBhAAEgQIDBAAEgQIAxAAEgQICRAAEgQIEBAAEgQIDhAAEgQIARAAEgQIDxAAEgQIERAAEgQIBRAAEgQICxAAEgQIAhAA; wosid-lite=jRoFTHWbZZZkSOfvfDELf0; mz_at_ssl-12263680861=AwUAAAECAAHXHQAAAABgqAeMT5/7LbF5106/zxFn9xH4n7jgwEw=; mz_at0-12263680861=AwQAAAECAAHXHQAAAABgp/7Z1enk1z4615lhp9QKlDQfmo7Hq60=; pldfltcid=524b36a58d0d4249a127affd05921dab046; X-Dsid=12263680861; xp_ab=1#WqjkRLH+-2+TCEF_ea00#yNFpB6B+-2+c9imSgD01; xp_abc=TCEF_ea00; mz_at0-10255130069=AwQAAAECAAHXHQAAAABgnNBzeacT12/WPi/iSOROyaMVQrfmkqE=; mz_at_ssl-10255130069=AwUAAAECAAHXHQAAAABgnNBzNHT9PbcrsAARLEWi0+8ElnKZ54c=; xp_ci=3z3h6Y0vzFQQz4XtzB5DzZvQkYhyo +X-Apple-AMD-M: rjK8HkwTcIoiOk6UoA9LXta0h/19+ss41RU7YLxGunAtLnl1Fus5i4VS56O71ifgDWwrEl/jIbPrDLfS +X-Apple-AMD: AAAABAAAABCqItI0AgfIcPIc0+zGpNtr +X-Apple-Store-Front: 143462-9,32 +Accept-Language: zh-cn +Date: Fri, 21 May 2021 21:33:42 GMT +X-Apple-MD-M: rjK8HkwTcIoiOk6UoA9LXta0h/2Qyn969daQuVAdJbkmCnWee7s+joaQ3fvc4v1JTJB0sUJcDwc0Q12z +X-Apple-I-MD-RINFO: 50660608 +X-Apple-I-MD-M: rjK8HkwTcIoiOk6UoA9LXta0h/0W22FXNYql4KAM12/n20O3iVf54IK85PbrLb51CvEfn5/b6eoX5d1d +X-Apple-I-MD: AAAABQAAABA+EMexoFPqOMeyQ5zIkQYPAAAAAg== +Accept-Encoding: gzip, deflate +Connection: close + + + + + guid + 46994789.C2E39C5C.B1D62DC2.025D2569.3D6E49B5.AB7F7EB4.F6D17565 + kbsync + + AAQAA5+HiDofKn/iW9aKVsKo1XU0cRuzPrQGMfC57fQaA7YaZBWlSS+s4SS2Ay6pchYG + x/h+cJccHMoA/NDtHcWsRl9nmDwzAnuW9WH7nHQAEt95wkj2eMQVBHyj3OSkSoEGFnS8 + r4irSIve3V4np1lvbEUgHdJmOEV6gAd8SFzItmgxFImn55qoUX/xt4pdXagPmhBXaYFI + +B/uYLxOYLO4fM1fGpQQ8/1EIpzrbahFjpG8L8kMjhVIWpn2Ut30p2deyjcL47JbSjx7 + /RId4XZlSEqXf9SOETcsxCkVhDWTghGYRWKlEe7j32CVrxOkg2lvlQLHB1XBhTpQiLSm + PR0hDIG5dQif0jaIeQJ9zGqq3kgkl9RlFHGbcvfMdrJsYGOgYMzXh1jfF/v21xPfauYh + PIE9LQu/TTiAGDvS+BYrM2xVaPHZPNUpLaVlk/2zIqiWo/Zj2se4FXGOl4LAVKqrbOYN + 2YONkSY4CQOZTmNmoO6SBU2NJHBYtVVeIhOLGLoS9/xzPwMdFevvZJFD7iQvL0RDKCBt + z5r7dnFz2WlZsdx0aMsbV3HRdnJtmBh7zA3AaO/4rJtWAQqAID2gAF8YMoNdJJp13Bdr + f34iRpVYbsDxrBNJXtanTgDdNO3xXpyZhQTgOrBDcsv7mD68E1E6bE5ac97/z9R8cLf0 + 8/X8/ie7tUBcqVThW81DiM4RGh3LSg== + + price + 0 + pricingParameters + STDRDL + productType + C + salableAdamId + 1234806557appExtVrsId + 839637337 + + +''' + +import sys +import codecs +import frida +import plistlib +import os +import base64 + +##### Frida Part + +procName = os.environ.get('ITUNES_PROCESS_NAME', 'iTunes.exe') +session = frida.attach(procName) +#session = frida.attach('iTunesFucked.exe') + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + +with codecs.open(os.path.dirname(os.path.realpath(__file__)) + '/get_header_rpc.js', 'r', 'utf-8') as f: + source = f.read() + +script = session.create_script(source) +script.load() + +def on_message(message, data): + if message['type'] == 'send': + eprint("Frida: %s" % message['payload']) + elif message['type'] == 'error': + eprint("Frida error: %s" % message['stack']) + +script.on('message', on_message) + +rpc = script.exports + + +##### Flask Part + +from flask import Flask, request +from flask import jsonify + +app = Flask(__name__) + +@app.route('/', methods=['GET', 'POST']) +def getHeader(): + hdrUrl = request.args.get('url', "https://p46-buy.itunes.apple.com/WebObjects/MZBuy.woa/wa/buyProduct") + retHdrs = rpc.get_header(hdrUrl) + eprint("Got Headers: %s" % retHdrs) + kbsync = retHdrs.pop('kbsync') + guid = retHdrs.pop('X-Guid') + return jsonify({ + "headers": retHdrs, + "kbsync": kbsync, + "guid": guid + }) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=9000) + +session.detach() \ No newline at end of file diff --git a/src_win/actions-iTunes-header/workflow_helper/iTunesDownload/get_header_rpc.js b/src_win/actions-iTunes-header/workflow_helper/iTunesDownload/get_header_rpc.js new file mode 100755 index 0000000..1efef57 --- /dev/null +++ b/src_win/actions-iTunes-header/workflow_helper/iTunesDownload/get_header_rpc.js @@ -0,0 +1,100 @@ +var getHeader = null; +function init() { + var CFURLCreateWithBytes = new NativeFunction(Module.findExportByName('CoreFoundation','CFURLCreateWithBytes'), 'pointer', ['pointer', 'pointer', 'int64', 'int64', 'int64']) + var CFDictionaryGetCount = new NativeFunction(Module.findExportByName('CoreFoundation','CFDictionaryGetCount'), 'int64', ['pointer']) + var CFCopyDescription = new NativeFunction(Module.findExportByName('CoreFoundation','CFCopyDescription'), 'pointer', ['pointer']) + var CFStringGetCStringPtr = new NativeFunction(Module.findExportByName('CoreFoundation','CFStringGetCStringPtr'), 'pointer', ['pointer', 'uint64']) + var CFStringGetCString = new NativeFunction(Module.findExportByName('CoreFoundation','CFStringGetCString'), 'int8', ['pointer', 'pointer', 'int64', 'int64']) + var CFStringGetLength = new NativeFunction(Module.findExportByName('CoreFoundation','CFStringGetLength'), 'int64', ['pointer']) + var CFDictionaryGetCount = new NativeFunction(Module.findExportByName('CoreFoundation','CFDictionaryGetCount'), 'int64', ['pointer']) + var CFDictionaryGetKeysAndValues = new NativeFunction(Module.findExportByName('CoreFoundation','CFDictionaryGetKeysAndValues'), 'void', ['pointer', 'pointer', 'pointer']) + var CFDataGetBytePtr = new NativeFunction(Module.findExportByName('CoreFoundation','CFDataGetBytePtr'), 'pointer', ['pointer']) + var CFDataGetLength = new NativeFunction(Module.findExportByName('CoreFoundation','CFDataGetLength'), 'uint64', ['pointer']) + + var readCFStr = (cfs) => { + var cfslen = CFStringGetLength(cfs) + var cfsBuf = Memory.alloc(cfslen + 1) + CFStringGetCString(cfs, cfsBuf, cfslen + 1, 134217984) + return Memory.readUtf8String(cfsBuf, cfslen) + } + + var readCFDict = (cfdict) => { + var dictCount = CFDictionaryGetCount(cfdict) + var dictKeys = Memory.alloc(dictCount * 8) + var dictValues = Memory.alloc(dictCount * 8) + CFDictionaryGetKeysAndValues(cfdict, dictKeys, dictValues) + var ret = {} + for (var i = 0; i < dictCount; i++) { + var k = readCFStr(dictKeys.add(8 * i).readPointer()) + var v = readCFStr(dictValues.add(8 * i).readPointer()) + ret[k] = v + } + return ret + } + + var readCFData = (cfd) => { + var cfdlen = CFDataGetLength(cfd) + var cfdbuf = CFDataGetBytePtr(cfd) + return cfdbuf.readByteArray(cfdlen) + } + + var itunesBase = Process.enumerateModulesSync()[0].base + var cfAllocator = itunesBase.add(0x22A8448).readPointer() + var kbsyncContext = itunesBase.add(0x22A6BBC).readU32() + var prepareAppleHdrWrap = new NativeFunction(itunesBase.add(0x87FFC0), 'pointer',['pointer','pointer','pointer']); + var get_cookie_val = new NativeFunction(itunesBase.add(0xBDE500), 'pointer',['pointer']); + var get_kbsync = new NativeFunction(itunesBase.add(0x74D210), 'pointer',['uint32', 'uint32', 'pointer']); + + getHeader = function (url) { + var GlobalContext = itunesBase.add(0x22A9B18).readPointer() + var otpGlobalContext = GlobalContext + if (!GlobalContext.isNull()) { + otpGlobalContext = GlobalContext.add(62716).readPointer() + } + + var otpContext = Memory.alloc(128) + otpContext.writePointer(otpGlobalContext) + otpContext.add(8).writeU64(0) + otpContext.add(16).writeU64(0) + otpContext.add(24).writeU16(1) + otpContext.add(26).writeU8(0) + otpContext.add(27).writeU8(1) // include X-Guid + otpContext.add(28).writeU8(1) // include ADIV1 Hdrs + otpContext.add(32).writeU32(0) + otpContext.add(36).writeU16(0) + otpContext.add(40).writeU32(0) + otpContext.add(48).writeU64(0) + otpContext.add(64).writeU64(0) + otpContext.add(72).writeU64(0) + otpContext.add(84).writeU64(0) + otpContext.add(112).writeU8(1) + + var urlBuf = Memory.allocUtf8String(url) + var urlData = CFURLCreateWithBytes(cfAllocator, urlBuf, url.length, 0x8000100, 0) + + var kbsync = get_kbsync(kbsyncContext, 1, otpGlobalContext) + + var cookieCFStr = get_cookie_val(urlData) + var hdrDict = prepareAppleHdrWrap(NULL, urlData, otpContext) + //hdrdesc = CFCopyDescription(hdrDict) + //console.log(readCFStr(hdrdesc)) + + var cookieStr = readCFStr(cookieCFStr) + var hdrOutput = readCFDict(hdrDict) + hdrOutput['Cookie'] = cookieStr + + var kbSyncData = readCFData(kbsync) + hdrOutput['kbsync'] = [...new Uint8Array(kbSyncData)].map(x => x.toString(16).padStart(2, '0')).join(''); + + return hdrOutput + }; +} + +rpc.exports = { + getHeader: (url) => { + if (!getHeader) { + init() + } + return getHeader(url); + }, +}; \ No newline at end of file diff --git a/src_win/actions-iTunes-header/workflow_helper/iTunesInstall/install_itunes.bat b/src_win/actions-iTunes-header/workflow_helper/iTunesInstall/install_itunes.bat new file mode 100755 index 0000000..6a6b62e --- /dev/null +++ b/src_win/actions-iTunes-header/workflow_helper/iTunesInstall/install_itunes.bat @@ -0,0 +1,13 @@ +cd %~dp0 + +curl -LO https://secure-appldnld.apple.com/itunes12/091-87819-20180912-69177170-B085-11E8-B6AB-C1D03409AD2A6/iTunes64Setup.exe +iTunes64Setup.exe /extract + +@REM start /wait msiexec.exe /i AppleApplicationSupport.msi /qn +start /wait msiexec.exe /i AppleApplicationSupport64.msi /qn +@REM start /wait msiexec.exe /i AppleMobileDeviceSupport64.msi /qn +@REM start /wait msiexec.exe /i AppleSoftwareUpdate.msi /qn +@REM start /wait msiexec.exe /i Bonjour64.msi /qn +start /wait msiexec.exe /i iTunes64.msi /qn + +python3 patch_itunes.py \ No newline at end of file diff --git a/src_win/actions-iTunes-header/workflow_helper/iTunesInstall/patch_itunes.py b/src_win/actions-iTunes-header/workflow_helper/iTunesInstall/patch_itunes.py new file mode 100755 index 0000000..fddcc6b --- /dev/null +++ b/src_win/actions-iTunes-header/workflow_helper/iTunesInstall/patch_itunes.py @@ -0,0 +1,22 @@ +import os + +# for debug +P = r"C:\Program Files\iTunes\iTunes1.exe" +if not os.path.exists(P): + # for production + P = r"C:\Program Files\iTunes\iTunes.exe" + +with open(P, 'rb') as f: + data = f.read() + +data = bytearray(data) + +# Patch passwordSettings (actually useless) +data[0x77daf4:0x77daf4+5] = b'\xBF\x03\x00\x00\x00' +data[0x77db7e:0x77db7e+2] = b'\xEB\x0A' + +# Patch signIn reason to serverDialog +data[0x7a9ed4:0x7a9ed4+6] = b'\xB9\x23\xFF\xFF\xFF\x90' + +with open(P, 'wb') as f: + f.write(data) \ No newline at end of file diff --git a/src_win/actions-iTunes-header/workflow_helper/itunes_auto_login.py b/src_win/actions-iTunes-header/workflow_helper/itunes_auto_login.py new file mode 100755 index 0000000..e5e6046 --- /dev/null +++ b/src_win/actions-iTunes-header/workflow_helper/itunes_auto_login.py @@ -0,0 +1,156 @@ +import subprocess +import time +from pywinauto.application import Application +from win32con import * +import sys + +ACCOUNT = sys.argv[1] +PASSWORD = sys.argv[2] + +print("Launching iTunes...") + +def initITunes(): + subprocess.call('taskkill /f /im iTunes*', shell=True) + + app = Application().start(r"C:\Program Files\iTunes\iTunes.exe") + app.wait_cpu_usage_lower() + time.sleep(8) + + def debugTopWin(): + topwin = app.top_window().wait('exists') + texts = [] + texts += topwin.texts() + for c in topwin.iter_children(): + texts += c.texts() + print("-- Cur top win: %s, texts: %s" % (topwin, texts)) + + def cleanAllDialog(): + while True: + topwin = app.top_window().wait('exists') + if 'Dialog' in topwin.class_name(): + print(" Closing dialog %s" % topwin.window_text()) + app.top_window().Button0.click() + elif 'Tour' in topwin.window_text(): + print(" Closing Window %s" % topwin.window_text()) + topwin.close() + else: + break + + app.wait_cpu_usage_lower() + time.sleep(5) + + # Click all first-time dialogs (like License Agreements, missing audios) + cleanAllDialog() + + # Calm down a bit before main window operations + app.wait_cpu_usage_lower() + debugTopWin() + + # Click main window's first-time question ("No thanks" button) + try: + buttonText = app.iTunes.Button11.wait('ready').window_text() + print('Button11 text is: %s' % buttonText) + if 'Search' not in buttonText: + print("Clicked 'No Thanks' Button!") + app.iTunes.Button11.click_input() + app.wait_cpu_usage_lower() + time.sleep(4) + else: + raise Exception('stub') + except: + print("Not founding 'No Thanks' Button, passing on...") + + + # Start logging in by clicking toolbar menu "Account" + print("Clicking Account menu...") + app.iTunes.Application.Static3.click() + app.wait_cpu_usage_lower() + time.sleep(3) + + debugTopWin() + + # Detect whether we have "&S" in popup, which refers to "Sign in" + popup = app.PopupMenu + if '&S' not in popup.menu().item(1).text(): + popup.close() + raise Exception("Already logged in!") + + print("Signin menu presented, clicking to login!") + # not log in + popup.menu().item(1).click_input() + app.wait_cpu_usage_lower() + time.sleep(8) + debugTopWin() + + for i in range(15): + dialog = app.top_window() + dialogWrap = dialog.wait('ready') + assert dialogWrap.friendly_class_name() == 'Dialog' + time.sleep(1.0) + try: + if dialogWrap.window_text() == 'iTunes' \ + and dialog.Edit1.wait('ready').window_text() == 'Apple ID' \ + and dialog.Edit2.wait('ready').window_text() == 'Password' \ + and dialog.Button1.wait('exists').window_text() == '&Sign In': + break + except Exception as e: + continue + else: + raise Exception("Failed to find login window in 15 iterations!") + app.wait_cpu_usage_lower() + + print("Setting login dialog edit texts") + + appleid_Edit = dialog.Edit1 + appleid_Edit.wait('ready') + appleid_Edit.click_input() + appleid_Edit.type_keys(ACCOUNT) + appleid_Edit.set_edit_text(ACCOUNT) + time.sleep(3) + + pass_Edit = dialog.Edit2 + pass_Edit.wait('ready') + pass_Edit.click_input() + pass_Edit.type_keys(PASSWORD) + pass_Edit.set_edit_text(PASSWORD) + time.sleep(3) + + print("Clicking login button!") + loginButton = dialog.Button1 + loginButton.wait('ready') + # click multiple times as pywinauto seems to have some bug + loginButton.click() + time.sleep(0.5) + try: + loginButton.click() + time.sleep(0.5) + loginButton.click_input() + except: + pass + + + print("Waiting login result...") + time.sleep(10) + debugTopWin() + + if app.top_window().handle == dialogWrap.handle: + raise Exception("Failed to trigger Login button!") + elif app.top_window().window_text() == 'Verification Failed': + raise Exception("Verification Failed: %s" % app.top_window().Static2.window_text()) + + + # Finish & Cleanup + print("Waiting all dialogs to finish") + cleanAllDialog() + + +for init_i in range(3): + try: + initITunes() + break + except Exception as e: + print("Init iTunes %d: Failed with %s" % (init_i, e)) + import traceback; traceback.print_exc() + time.sleep(8) + +print("Init iTunes Successfully!") \ No newline at end of file diff --git a/src_win/libimobiledevice/README.md b/src_win/libimobiledevice/README.md new file mode 100755 index 0000000..b3552ef --- /dev/null +++ b/src_win/libimobiledevice/README.md @@ -0,0 +1,2 @@ +Libimobiledevice compiled for Windows +Updated 18/05/2020. Compiled by iFred09 \ No newline at end of file diff --git a/src_win/libimobiledevice/idevice_id.exe b/src_win/libimobiledevice/idevice_id.exe new file mode 100755 index 0000000..dd4887e Binary files /dev/null and b/src_win/libimobiledevice/idevice_id.exe differ diff --git a/src_win/libimobiledevice/ideviceactivation.exe b/src_win/libimobiledevice/ideviceactivation.exe new file mode 100755 index 0000000..1ece30e Binary files /dev/null and b/src_win/libimobiledevice/ideviceactivation.exe differ diff --git a/src_win/libimobiledevice/idevicebackup.exe b/src_win/libimobiledevice/idevicebackup.exe new file mode 100755 index 0000000..8d35757 Binary files /dev/null and b/src_win/libimobiledevice/idevicebackup.exe differ diff --git a/src_win/libimobiledevice/idevicebackup2.exe b/src_win/libimobiledevice/idevicebackup2.exe new file mode 100755 index 0000000..a239b88 Binary files /dev/null and b/src_win/libimobiledevice/idevicebackup2.exe differ diff --git a/src_win/libimobiledevice/idevicecrashreport.exe b/src_win/libimobiledevice/idevicecrashreport.exe new file mode 100755 index 0000000..e636f8a Binary files /dev/null and b/src_win/libimobiledevice/idevicecrashreport.exe differ diff --git a/src_win/libimobiledevice/idevicedate.exe b/src_win/libimobiledevice/idevicedate.exe new file mode 100755 index 0000000..debe083 Binary files /dev/null and b/src_win/libimobiledevice/idevicedate.exe differ diff --git a/src_win/libimobiledevice/idevicedebug.exe b/src_win/libimobiledevice/idevicedebug.exe new file mode 100755 index 0000000..0a8e8b1 Binary files /dev/null and b/src_win/libimobiledevice/idevicedebug.exe differ diff --git a/src_win/libimobiledevice/idevicedebugserverproxy.exe b/src_win/libimobiledevice/idevicedebugserverproxy.exe new file mode 100755 index 0000000..dc3227e Binary files /dev/null and b/src_win/libimobiledevice/idevicedebugserverproxy.exe differ diff --git a/src_win/libimobiledevice/idevicediagnostics.exe b/src_win/libimobiledevice/idevicediagnostics.exe new file mode 100755 index 0000000..4643e2d Binary files /dev/null and b/src_win/libimobiledevice/idevicediagnostics.exe differ diff --git a/src_win/libimobiledevice/ideviceenterrecovery.exe b/src_win/libimobiledevice/ideviceenterrecovery.exe new file mode 100755 index 0000000..4a4c92f Binary files /dev/null and b/src_win/libimobiledevice/ideviceenterrecovery.exe differ diff --git a/src_win/libimobiledevice/ideviceimagemounter.exe b/src_win/libimobiledevice/ideviceimagemounter.exe new file mode 100755 index 0000000..09a2741 Binary files /dev/null and b/src_win/libimobiledevice/ideviceimagemounter.exe differ diff --git a/src_win/libimobiledevice/ideviceinfo.exe b/src_win/libimobiledevice/ideviceinfo.exe new file mode 100755 index 0000000..272b4dd Binary files /dev/null and b/src_win/libimobiledevice/ideviceinfo.exe differ diff --git a/src_win/libimobiledevice/ideviceinstaller.exe b/src_win/libimobiledevice/ideviceinstaller.exe new file mode 100755 index 0000000..6a26411 Binary files /dev/null and b/src_win/libimobiledevice/ideviceinstaller.exe differ diff --git a/src_win/libimobiledevice/idevicename.exe b/src_win/libimobiledevice/idevicename.exe new file mode 100755 index 0000000..73a2d51 Binary files /dev/null and b/src_win/libimobiledevice/idevicename.exe differ diff --git a/src_win/libimobiledevice/idevicenotificationproxy.exe b/src_win/libimobiledevice/idevicenotificationproxy.exe new file mode 100755 index 0000000..ed3f862 Binary files /dev/null and b/src_win/libimobiledevice/idevicenotificationproxy.exe differ diff --git a/src_win/libimobiledevice/idevicepair.exe b/src_win/libimobiledevice/idevicepair.exe new file mode 100755 index 0000000..e5686d2 Binary files /dev/null and b/src_win/libimobiledevice/idevicepair.exe differ diff --git a/src_win/libimobiledevice/ideviceprovision.exe b/src_win/libimobiledevice/ideviceprovision.exe new file mode 100755 index 0000000..355fa8d Binary files /dev/null and b/src_win/libimobiledevice/ideviceprovision.exe differ diff --git a/src_win/libimobiledevice/idevicerestore.exe b/src_win/libimobiledevice/idevicerestore.exe new file mode 100755 index 0000000..d9895e9 Binary files /dev/null and b/src_win/libimobiledevice/idevicerestore.exe differ diff --git a/src_win/libimobiledevice/idevicescreenshot.exe b/src_win/libimobiledevice/idevicescreenshot.exe new file mode 100755 index 0000000..d7ea51d Binary files /dev/null and b/src_win/libimobiledevice/idevicescreenshot.exe differ diff --git a/src_win/libimobiledevice/idevicesetlocation.exe b/src_win/libimobiledevice/idevicesetlocation.exe new file mode 100755 index 0000000..1dbebc9 Binary files /dev/null and b/src_win/libimobiledevice/idevicesetlocation.exe differ diff --git a/src_win/libimobiledevice/idevicesyslog.exe b/src_win/libimobiledevice/idevicesyslog.exe new file mode 100755 index 0000000..fe78fd8 Binary files /dev/null and b/src_win/libimobiledevice/idevicesyslog.exe differ diff --git a/src_win/libimobiledevice/inetcat.exe b/src_win/libimobiledevice/inetcat.exe new file mode 100755 index 0000000..99211f4 Binary files /dev/null and b/src_win/libimobiledevice/inetcat.exe differ diff --git a/src_win/libimobiledevice/iproxy.exe b/src_win/libimobiledevice/iproxy.exe new file mode 100755 index 0000000..310d2a3 Binary files /dev/null and b/src_win/libimobiledevice/iproxy.exe differ diff --git a/src_win/libimobiledevice/irecovery.exe b/src_win/libimobiledevice/irecovery.exe new file mode 100755 index 0000000..5701b24 Binary files /dev/null and b/src_win/libimobiledevice/irecovery.exe differ diff --git a/src_win/libimobiledevice/libbrotlicommon.dll b/src_win/libimobiledevice/libbrotlicommon.dll new file mode 100755 index 0000000..45224ba Binary files /dev/null and b/src_win/libimobiledevice/libbrotlicommon.dll differ diff --git a/src_win/libimobiledevice/libbrotlidec.dll b/src_win/libimobiledevice/libbrotlidec.dll new file mode 100755 index 0000000..286ed8a Binary files /dev/null and b/src_win/libimobiledevice/libbrotlidec.dll differ diff --git a/src_win/libimobiledevice/libbz2-1.dll b/src_win/libimobiledevice/libbz2-1.dll new file mode 100755 index 0000000..b4281bc Binary files /dev/null and b/src_win/libimobiledevice/libbz2-1.dll differ diff --git a/src_win/libimobiledevice/libcrypto-1_1.dll b/src_win/libimobiledevice/libcrypto-1_1.dll new file mode 100755 index 0000000..edbf911 Binary files /dev/null and b/src_win/libimobiledevice/libcrypto-1_1.dll differ diff --git a/src_win/libimobiledevice/libcurl-4.dll b/src_win/libimobiledevice/libcurl-4.dll new file mode 100755 index 0000000..e68a795 Binary files /dev/null and b/src_win/libimobiledevice/libcurl-4.dll differ diff --git a/src_win/libimobiledevice/libeay32.dll b/src_win/libimobiledevice/libeay32.dll new file mode 100755 index 0000000..8b58883 Binary files /dev/null and b/src_win/libimobiledevice/libeay32.dll differ diff --git a/src_win/libimobiledevice/libffi-6.dll b/src_win/libimobiledevice/libffi-6.dll new file mode 100755 index 0000000..f87af2d Binary files /dev/null and b/src_win/libimobiledevice/libffi-6.dll differ diff --git a/src_win/libimobiledevice/libgcc_s_dw2-1.dll b/src_win/libimobiledevice/libgcc_s_dw2-1.dll new file mode 100755 index 0000000..b5fcaea Binary files /dev/null and b/src_win/libimobiledevice/libgcc_s_dw2-1.dll differ diff --git a/src_win/libimobiledevice/libgmp-10.dll b/src_win/libimobiledevice/libgmp-10.dll new file mode 100755 index 0000000..9886875 Binary files /dev/null and b/src_win/libimobiledevice/libgmp-10.dll differ diff --git a/src_win/libimobiledevice/libgnutls-30.dll b/src_win/libimobiledevice/libgnutls-30.dll new file mode 100755 index 0000000..fc8bab8 Binary files /dev/null and b/src_win/libimobiledevice/libgnutls-30.dll differ diff --git a/src_win/libimobiledevice/libhogweed-4-2.dll b/src_win/libimobiledevice/libhogweed-4-2.dll new file mode 100755 index 0000000..b22e140 Binary files /dev/null and b/src_win/libimobiledevice/libhogweed-4-2.dll differ diff --git a/src_win/libimobiledevice/libhogweed-4.dll b/src_win/libimobiledevice/libhogweed-4.dll new file mode 100755 index 0000000..d19df46 Binary files /dev/null and b/src_win/libimobiledevice/libhogweed-4.dll differ diff --git a/src_win/libimobiledevice/libiconv-2.dll b/src_win/libimobiledevice/libiconv-2.dll new file mode 100755 index 0000000..0b3b8b6 Binary files /dev/null and b/src_win/libimobiledevice/libiconv-2.dll differ diff --git a/src_win/libimobiledevice/libideviceactivation-2.dll b/src_win/libimobiledevice/libideviceactivation-2.dll new file mode 100755 index 0000000..5c61dd0 Binary files /dev/null and b/src_win/libimobiledevice/libideviceactivation-2.dll differ diff --git a/src_win/libimobiledevice/libideviceactivation.dll b/src_win/libimobiledevice/libideviceactivation.dll new file mode 100755 index 0000000..98db389 Binary files /dev/null and b/src_win/libimobiledevice/libideviceactivation.dll differ diff --git a/src_win/libimobiledevice/libidn-11.dll b/src_win/libimobiledevice/libidn-11.dll new file mode 100755 index 0000000..aa894ca Binary files /dev/null and b/src_win/libimobiledevice/libidn-11.dll differ diff --git a/src_win/libimobiledevice/libidn2-0.dll b/src_win/libimobiledevice/libidn2-0.dll new file mode 100755 index 0000000..a1db430 Binary files /dev/null and b/src_win/libimobiledevice/libidn2-0.dll differ diff --git a/src_win/libimobiledevice/libimobiledevice.dll b/src_win/libimobiledevice/libimobiledevice.dll new file mode 100755 index 0000000..25f9ca1 Binary files /dev/null and b/src_win/libimobiledevice/libimobiledevice.dll differ diff --git a/src_win/libimobiledevice/libintl-8.dll b/src_win/libimobiledevice/libintl-8.dll new file mode 100755 index 0000000..1e56815 Binary files /dev/null and b/src_win/libimobiledevice/libintl-8.dll differ diff --git a/src_win/libimobiledevice/libirecovery.dll b/src_win/libimobiledevice/libirecovery.dll new file mode 100755 index 0000000..37da24a Binary files /dev/null and b/src_win/libimobiledevice/libirecovery.dll differ diff --git a/src_win/libimobiledevice/liblzma-5.dll b/src_win/libimobiledevice/liblzma-5.dll new file mode 100755 index 0000000..57514a3 Binary files /dev/null and b/src_win/libimobiledevice/liblzma-5.dll differ diff --git a/src_win/libimobiledevice/libnettle-6-2.dll b/src_win/libimobiledevice/libnettle-6-2.dll new file mode 100755 index 0000000..ebd02fe Binary files /dev/null and b/src_win/libimobiledevice/libnettle-6-2.dll differ diff --git a/src_win/libimobiledevice/libnettle-6.dll b/src_win/libimobiledevice/libnettle-6.dll new file mode 100755 index 0000000..bf002e3 Binary files /dev/null and b/src_win/libimobiledevice/libnettle-6.dll differ diff --git a/src_win/libimobiledevice/libnghttp2-14.dll b/src_win/libimobiledevice/libnghttp2-14.dll new file mode 100755 index 0000000..4e54eec Binary files /dev/null and b/src_win/libimobiledevice/libnghttp2-14.dll differ diff --git a/src_win/libimobiledevice/libp11-kit-0.dll b/src_win/libimobiledevice/libp11-kit-0.dll new file mode 100755 index 0000000..a0dc49a Binary files /dev/null and b/src_win/libimobiledevice/libp11-kit-0.dll differ diff --git a/src_win/libimobiledevice/libplist++-3.dll b/src_win/libimobiledevice/libplist++-3.dll new file mode 100755 index 0000000..5362d0d Binary files /dev/null and b/src_win/libimobiledevice/libplist++-3.dll differ diff --git a/src_win/libimobiledevice/libplist++.dll b/src_win/libimobiledevice/libplist++.dll new file mode 100755 index 0000000..e482749 Binary files /dev/null and b/src_win/libimobiledevice/libplist++.dll differ diff --git a/src_win/libimobiledevice/libplist.dll b/src_win/libimobiledevice/libplist.dll new file mode 100755 index 0000000..4e3ceed Binary files /dev/null and b/src_win/libimobiledevice/libplist.dll differ diff --git a/src_win/libimobiledevice/libpsl-5.dll b/src_win/libimobiledevice/libpsl-5.dll new file mode 100755 index 0000000..5e0546f Binary files /dev/null and b/src_win/libimobiledevice/libpsl-5.dll differ diff --git a/src_win/libimobiledevice/libreadline6.dll b/src_win/libimobiledevice/libreadline6.dll new file mode 100755 index 0000000..80e1174 Binary files /dev/null and b/src_win/libimobiledevice/libreadline6.dll differ diff --git a/src_win/libimobiledevice/libreadline8.dll b/src_win/libimobiledevice/libreadline8.dll new file mode 100755 index 0000000..9a96f9b Binary files /dev/null and b/src_win/libimobiledevice/libreadline8.dll differ diff --git a/src_win/libimobiledevice/librtmp-1.dll b/src_win/libimobiledevice/librtmp-1.dll new file mode 100755 index 0000000..5ac48a3 Binary files /dev/null and b/src_win/libimobiledevice/librtmp-1.dll differ diff --git a/src_win/libimobiledevice/libssh2-1.dll b/src_win/libimobiledevice/libssh2-1.dll new file mode 100755 index 0000000..45edc87 Binary files /dev/null and b/src_win/libimobiledevice/libssh2-1.dll differ diff --git a/src_win/libimobiledevice/libssl-1_1.dll b/src_win/libimobiledevice/libssl-1_1.dll new file mode 100755 index 0000000..5e870f8 Binary files /dev/null and b/src_win/libimobiledevice/libssl-1_1.dll differ diff --git a/src_win/libimobiledevice/libtasn1-6.dll b/src_win/libimobiledevice/libtasn1-6.dll new file mode 100755 index 0000000..e0de286 Binary files /dev/null and b/src_win/libimobiledevice/libtasn1-6.dll differ diff --git a/src_win/libimobiledevice/libtermcap-0.dll b/src_win/libimobiledevice/libtermcap-0.dll new file mode 100755 index 0000000..822d49d Binary files /dev/null and b/src_win/libimobiledevice/libtermcap-0.dll differ diff --git a/src_win/libimobiledevice/libunistring-2.dll b/src_win/libimobiledevice/libunistring-2.dll new file mode 100755 index 0000000..3349a00 Binary files /dev/null and b/src_win/libimobiledevice/libunistring-2.dll differ diff --git a/src_win/libimobiledevice/libusbmuxd.dll b/src_win/libimobiledevice/libusbmuxd.dll new file mode 100755 index 0000000..66d0765 Binary files /dev/null and b/src_win/libimobiledevice/libusbmuxd.dll differ diff --git a/src_win/libimobiledevice/libwinpthread-1.dll b/src_win/libimobiledevice/libwinpthread-1.dll new file mode 100755 index 0000000..6614177 Binary files /dev/null and b/src_win/libimobiledevice/libwinpthread-1.dll differ diff --git a/src_win/libimobiledevice/libxml2-2.dll b/src_win/libimobiledevice/libxml2-2.dll new file mode 100755 index 0000000..9c9b3ce Binary files /dev/null and b/src_win/libimobiledevice/libxml2-2.dll differ diff --git a/src_win/libimobiledevice/libzip-4.dll b/src_win/libimobiledevice/libzip-4.dll new file mode 100755 index 0000000..9d61bb7 Binary files /dev/null and b/src_win/libimobiledevice/libzip-4.dll differ diff --git a/src_win/libimobiledevice/libzip.dll b/src_win/libimobiledevice/libzip.dll new file mode 100755 index 0000000..4908ce5 Binary files /dev/null and b/src_win/libimobiledevice/libzip.dll differ diff --git a/src_win/libimobiledevice/plistutil.exe b/src_win/libimobiledevice/plistutil.exe new file mode 100755 index 0000000..4db9e6c Binary files /dev/null and b/src_win/libimobiledevice/plistutil.exe differ diff --git a/src_win/libimobiledevice/ssleay32.dll b/src_win/libimobiledevice/ssleay32.dll new file mode 100755 index 0000000..5b63dc2 Binary files /dev/null and b/src_win/libimobiledevice/ssleay32.dll differ diff --git a/src_win/libimobiledevice/zlib1.dll b/src_win/libimobiledevice/zlib1.dll new file mode 100755 index 0000000..ff0b039 Binary files /dev/null and b/src_win/libimobiledevice/zlib1.dll differ diff --git a/src_win/queued/place_ipas_here.txt b/src_win/queued/place_ipas_here.txt new file mode 100644 index 0000000..e69de29 diff --git a/src_win/win_server.py b/src_win/win_server.py new file mode 100755 index 0000000..d31059d --- /dev/null +++ b/src_win/win_server.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +from http.server import BaseHTTPRequestHandler, HTTPServer +from pathlib import Path +import os +import socket +import subprocess + +os.chdir(Path(__file__).parent) +INSTALLER = Path('libimobiledevice', 'ideviceinstaller.exe') +PATH_IN = Path('queued') + + +class IpaServer(BaseHTTPRequestHandler): + def reply(self, status: int, data: str): + self.send_response(status) + self.send_header('Access-Control-Allow-Origin', '*') + self.send_header('Content-type', 'text/plain') + self.end_headers() + self.wfile.write(data.encode('utf8')) + + def do_POST(self): + length = self.headers.get('Content-Length', 1) + data = self.rfile.read(int(length)).decode('utf8') + if self.path == '/up': + return self.reply(200, 'YES') + elif self.path == '/install': + fname = PATH_IN / data + if not fname.exists(): + return self.reply(404, f'File not found "{fname}"') + subprocess.run([INSTALLER, '-i', fname]) + elif self.path == '/uninstall': + bundleId = data + subprocess.run([INSTALLER, '-U', bundleId], timeout=60) + else: + raise ValueError('unsuppoted API path') + return self.reply(200, 'OK') + + +def getLocalIp(): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect(('10.255.255.255', 80)) + ip = s.getsockname()[0] + s.close() + return ip + + +if __name__ == '__main__': + webServer = HTTPServer(('0.0.0.0', 8117), IpaServer) + print('Server started http://%s:%s' % (getLocalIp(), 8117)) + try: + webServer.serve_forever() + except KeyboardInterrupt: + pass + webServer.server_close()