summaryrefslogtreecommitdiff
path: root/rustore-apk-get
diff options
context:
space:
mode:
Diffstat (limited to 'rustore-apk-get')
-rwxr-xr-xrustore-apk-get139
1 files changed, 139 insertions, 0 deletions
diff --git a/rustore-apk-get b/rustore-apk-get
new file mode 100755
index 0000000..5479c5d
--- /dev/null
+++ b/rustore-apk-get
@@ -0,0 +1,139 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+# See https://github.com/ImranR98/Obtainium/blob/main/lib/app_sources/rustore.dart
+
+# @describe Download apk from https://rustore.ru
+# @meta require-tools curl,jq,fzf,xxh64sum
+# @flag -u --update download file if it exists but hash not match
+# @flag -v --verbose verbose output
+# @flag --whats-new show whats new before download
+# @flag --save-json save package info JSON
+# @flag --extract extract ZIP on download
+# @option -q --query search string
+# @option -o --output=`_default_output` Output directory/file
+# @arg package_name Application package name
+
+BASE_URL=https://backapi.rustore.ru
+PAGE_SIZE=10
+
+_default_output() {
+ pwd
+}
+
+_curl() {
+ curl --retry 3 --header 'ruStoreVerCode: 1105002' "$@"
+}
+
+_curl_silent() {
+ _curl --silent "$@"
+}
+
+select_package_name_from_query() {
+ local delimiter=$'\t'
+ _curl_silent --get \
+ --data-urlencode "query=$argc_query" \
+ --data-urlencode "pageSize=$PAGE_SIZE" \
+ "$BASE_URL/applicationData/apps" |
+ jq -r '.body.content[] | [.packageName,.appName,.shortDescription] | @tsv' |
+ column -t -s "$delimiter" -o "$delimiter" |
+ fzf --delimiter "$delimiter" --accept-nth 1
+}
+
+get_app_info_by_package() {
+ _curl_silent --get "$BASE_URL/applicationData/overallInfo/$1" | jq .body
+}
+
+download_apk() {
+ local app_info="$1"
+ local app_id
+ local package_name
+ local version_name
+ app_id=$(jq -r .appId <<<"$app_info")
+ package_name=$(jq -r .packageName <<<"$app_info")
+ version_name=$(jq -r .versionName <<<"$app_info")
+ local output_file
+ local output_file_hash
+
+ if [ -d "${argc_output?}" ]; then
+ output_file="$argc_output/$package_name-$version_name.apk"
+ else
+ output_file="$argc_output"
+ fi
+ output_file_hash="${output_file}.xxh64sum"
+
+ local existing_file_hash
+
+ if [ -f "$output_file" ] && [ -f "$output_file_hash" ]; then
+ if [ -z "${argc_update:-}" ]; then
+ echo "File already exists: $output_file"
+ exit 1
+ else
+ existing_file_hash=$(cat "$output_file_hash")
+ fi
+ fi
+
+ local download_info
+ download_info=$(_curl_silent --request POST --json '{"appId":'"$app_id"'}' "$BASE_URL/applicationData/v2/download-link" | jq .body.downloadUrls[0])
+
+ local download_url
+ local expected_hash
+ download_url=$(jq -r .url <<<"$download_info")
+ expected_hash=$(jq -r .hash <<<"$download_info")
+
+ [ "${existing_file_hash:-}" == "$expected_hash" ] && return
+
+ [ -n "${argc_whats_new:-}" ] && jq -r '"News: \(.whatsNew)"' <<<"$app_info"
+
+ temp_file_zip=$(mktemp)
+ temp_file_apk=$(mktemp)
+ trap 'rm -f "$temp_file_zip" "$temp_file_apk"' EXIT
+
+ _curl --progress-bar --output "$temp_file_zip" "$download_url"
+
+ existing_file_hash=$(xxh64sum "$temp_file_zip" | cut -d ' ' -f 1)
+
+ if [ "$existing_file_hash" == "$expected_hash" ]; then
+ unzip -p "$temp_file_zip" "*.apk" >"$temp_file_apk"
+ mv "$temp_file_apk" "$output_file"
+ echo "$expected_hash" >"$output_file_hash"
+ else
+ echo "Downloaded file hash not match expected"
+ exit 2
+ fi
+}
+
+main() {
+ local package_name="${argc_package_name:-}"
+ if [[ "$package_name" == http* ]]; then
+ package_name=$(echo "$package_name" | grep -oP '(?<=/app/)[^/?]+')
+ fi
+ if [ -z "$package_name" ] && [ -n "${argc_query:-}" ]; then
+ package_name=$(select_package_name_from_query)
+ fi
+
+ [ -z "$package_name" ] && exit 1
+
+ local app_info
+ app_info=$(get_app_info_by_package "$package_name")
+
+ local app_id
+ app_id=$(jq -r .appId <<<"$app_info")
+
+ if [ -z "${app_id:-}" ]; then
+ echo "No application ID specified or found"
+ exit 1
+ fi
+
+ if [ "${argc_verbose:-}" == 1 ]; then
+ jq -r '{appName,versionName,appVerUpdatedAt,shortDescription,whatsNew} | to_entries[] | [.key,.value] | @tsv' <<<"$app_info" |
+ column -t -s $'\t'
+ else
+ jq -r '"\(.appName) - v\(.versionName) [\(.appVerUpdatedAt | strptime("%Y-%m-%dT%H:%M:%S%Z") | strftime("%d.%m.%Y"))]"' <<<"$app_info"
+ fi
+
+ download_apk "$app_info"
+}
+
+eval "$(argc --argc-eval "$0" "$@")"