#!/bin/bash # Functions borrowed or derived from # Michael Bryant / Shadow53 # https://gitlab.com/Shadow53/android-zip-builder repo_fdroid="https://f-droid.org/repo" repo_guardian="https://guardianproject.info/fdroid/repo" repo_microg="https://microg.org/fdroid/repo" repo_nanolx="https://nanolx.org/fdroid/repo" repo_bromite="https://fdroid.bromite.org/fdroid/repo" repo_ogapps="https://gitlab.opengapps.org/opengapps" repo_newpipe="https://archive.newpipe.net/fdroid/repo" useragent='Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0' if [ "${BP_DEBUG}" = '1' ]; then wget_opts="-v --show-progress" curl_opts="-vSL" else wget_opts="-q" curl_opts="-sSL" fi # check dependencies for dep in gawk curl jq zstd grep; do if ! which ${dep} &>/dev/null; then echo "${dep} is not installed!" exit 1 fi done zstd_apk () { [ -f "${1}" ] && \ zstd -1fq --rm "${1}" || \ echo "error downloading ${1}" } msg_no_checksum () { echo -e "\tChecking SHA256 hash not supported" } msg_apk_update () { if [ -f "${1}.zst" ]; then echo -e "\nUpdating from ${2} : $(basename ${1}) ${3}" else echo -e "\nDownloading from ${2} : $(basename ${1}) ${3}" fi } msg_download_info () { case ${1} in sideload) echo -e "\nSideloading APK : ${2} ${3}" msg_no_checksum ;; github) msg_apk_update "${2}" "GitHub" msg_no_checksum ;; gitlab) msg_apk_update "${2}" "GitLab" msg_no_checksum ;; opengapps) msg_apk_update "${2}" "OpenGApps" "${3}" msg_no_checksum ;; url) msg_apk_update "${2}" "URL" msg_no_checksum ;; esac } download_apk_common () { local apk_dest="${1}" local apk_name="${2}" local apk_url="${3}" local msg_type="${4}" [ -n "${5}" ] && local sdk_ver="[${5}]" mkdir -p "${apk_dest}" if [ -f "${sideload}/${apk_name}.apk" ]; then msg_download_info sideload "${apk_dest}/${apk_name}.apk" "${sdk_ver}" cp "${sideload}/${apk_name}.apk" "${apk_dest}/${apk_name}.apk" else msg_download_info "${msg_type}" "${apk_dest}/${apk_name}.apk" "${sdk_ver}" debug_download delete "${apk_dest}/${apk_name}.apk" "${apk_url}" "${apk_dest}/${apk_name}.apk" fi zstd_apk "${apk_dest}/${apk_name}.apk" } debug_download () { case $1 in index) if [ "${BP_USE_WGET}" = '1' ]; then rm -rf "$2" debug_message normal "wget ${wget_opts} \"$3\" -O \"${2#$CWD/}\"" " " wget ${wget_opts} -U "${useragent}" "$3" -O "$2" || error "$4" else debug_message normal "curl ${curl_opts} \"${2#$CWD/}\" \"$3\"" " " curl ${curl_opts} -A "${useragent}" -o "$2" "$3" || error "$4" fi ;; no_delete) if [ "${BP_USE_WGET}" = '1' ]; then rm -rf "$2" debug_message normal "wget ${wget_opts} \"$3\" -O \"${2#$CWD/}\"" wget ${wget_opts} -U "${useragent}" "$3" -O "$2" else debug_message normal "curl ${curl_opts} -SL -o \"${2#$CWD/}\" \"$3\"" curl ${curl_opts} -A "${useragent}" -o "$2" "$3" fi ;; delete) if [ "${BP_USE_WGET}" = '1' ]; then rm -rf "$2" debug_message normal "wget ${wget_opts} \"$3\" -O \"${2#$CWD/}\"" wget ${wget_opts} -U "${useragent}" "$3" -O "$2" || rm -f "$4" else debug_message normal "curl ${curl_opts} -SL -o \"${2#$CWD/}\" \"$3\"" curl ${curl_opts} -A "${useragent}" -o "$2" "$3" || rm -f "$4" fi ;; esac } index_update_required () { index_file=${1} test ! -f ${index_file} && return 0 test $(${statx} ${index_file}) -le $(($(date +%s) - 3600)) && return 0 test "$(file -b ${index_file})" == "empty" && return 0 return 1 } check_sha256sum () { local input="${1}" local in_checksum="" local ex_checksum="${2}" case ${input} in *.zst ) in_checksum=$(zstd -dcf ${input} 2>/dev/null | ${sumsha256} | gawk '{print $1}') ;; * ) in_checksum=$(${sumsha256} ${input} 2>/dev/null | gawk '{print $1}') ;; esac [[ ${in_checksum} == ${ex_checksum} ]] && return 0 || return 1 } update_index () { local index_jar=${1} local index_json="$repofolder/$(basename ${index_jar} .jar).json" local index_repo=${2} if index_update_required ${index_json}; then debug_download index "${index_jar}" "${index_repo}/index-v1.jar" " failed to update repo index" unzip -q ${index_jar} index-v1.json -d "$repofolder/" mv "$repofolder/index-v1.json" "${index_json}" rm -f ${index_jar} fi } update_indices () { echo "+++ upating Repo Indices" echo " ++ F-Droid" [ ! -d "$repofolder" ] && rm -rf "$repofolder" && mkdir -p "$repofolder" update_index "$repofolder/$(awk -F/ '{print $3}' <<< ${repo_fdroid}).index-v1.jar" "${repo_fdroid}" echo " ++ Guardian Project" update_index "$repofolder/$(awk -F/ '{print $3}' <<< ${repo_guardian}).index-v1.jar" "${repo_guardian}" echo " ++ microG" update_index "$repofolder/$(awk -F/ '{print $3}' <<< ${repo_microg}).index-v1.jar" "${repo_microg}" echo " ++ Nanolx" update_index "$repofolder/$(awk -F/ '{print $3}' <<< ${repo_nanolx}).index-v1.jar" "${repo_nanolx}" echo " ++ Bromite" update_index "$repofolder/$(awk -F/ '{print $3}' <<< ${repo_bromite}).index-v1.jar" "${repo_bromite}" echo " ++ NewPipe" update_index "$repofolder/$(awk -F/ '{print $3}' <<< ${repo_newpipe}).index-v1.jar" "${repo_newpipe}" } grab_apk_from_repo () { case "${1}" in fdroid ) local repo=${repo_fdroid} local repo_p="F-Droid" ;; guardian ) local repo=${repo_guardian} local repo_p="Guardian Project" ;; microg ) local repo=${repo_microg} local repo_p="microG" ;; nanolx ) local repo=${repo_nanolx} local repo_p="Nanolx" ;; bromite ) local repo=${repo_bromite} local repo_p="Bromite" ;; newpipe ) local repo=${repo_newpipe} local repo_p="NewPipe" ;; esac local domain="$(awk -F/ '{print $3}' <<< ${repo})" index_file="$repofolder/${domain}.index-v1.json" local pkg_name="${2}" if [ -z "${5}" ]; then local apk_name="$(jq -r --arg pkg "${pkg_name}" '.packages[$pkg][0].apkName' ${index_file})" local sha_sum="$(jq -r --arg pkg "${pkg_name}" '.packages[$pkg][0].hash' ${index_file})" else local apk_name="$(jq -r --arg pkg "${pkg_name}" --arg arch "${5}" '[.packages[$pkg][] | select (.nativecode[]==$arch).apkName][0]' ${index_file})" local sha_sum="$(jq -r --arg pkg "${pkg_name}" --arg arch "${5}" '[.packages[$pkg][] | select (.nativecode[]==$arch).hash][0]' ${index_file})" fi case "${pkg_name}" in org.bromite.webview ) local apk_dest="${appsfolder[12]}/${3}/${4}" ;; net.osmand.plus | net.osmand.srtmPlugin.paid ) local apk_dest="${appsfolder[10]}/${3}/${4}" ;; * ) local apk_dest="${appsfolder[2]}/${3}/${4}" ;; esac local apk_url="${repo}/${apk_name}" if [ -f "${sideload}/${4}.apk" ]; then echo -e "\nSideloading APK : ${4}.apk" mkdir -p "${apk_dest}" rm -f "${apk_dest}/${4}.apk.zst" cp "${sideload}/${4}.apk" "${apk_dest}/${4}.apk" zstd_apk "${apk_dest}/${4}.apk" else if check_sha256sum "${apk_dest}/${4}.apk.zst" "${sha_sum}"; then echo -e "\nUp-to-Date from ${repo_p} : ${4}.apk" else echo -e "\nUpdating from ${repo_p} : ${4}.apk" mkdir -p "${apk_dest}" rm -f "${apk_dest}/${4}.apk.zst" debug_download no_delete "${apk_dest}/${4}.apk" "${apk_url}" if check_sha256sum "${apk_dest}/${4}.apk" "${sha_sum}"; then echo " SHA256 hash of ${4}.apk is correct" zstd_apk "${apk_dest}/${4}.apk" else echo -e " SHA256 hash of ${4}.apk is wrong!\ \n expected : ${sha_sum}\ \n got : ${in_checksum}" rm -f "${apk_dest}/${4}.apk" fi fi fi } grab_apk_from_url () { local apk_url="${1}" local apk_dest="${appsfolder[2]}/${2}/${3}" download_apk_common "${apk_dest}" "${3}" "${apk_url}" url } grab_apk_from_github () { [ "${BP_DEBUG}" = '1' ] && debug_message normal "curl ${curl_opts} -s -N \"https://api.github.com/repos/${1}/releases\"" local apk_url="$(curl -A "${useragent}" -s "https://api.github.com/repos/${1}/releases/latest" | jq -r '.assets[0].browser_download_url')" local apk_dest="${appsfolder[2]}/${2}/${3}" download_apk_common "${apk_dest}" "${3}" "${apk_url}" github } grab_apk_from_gitlab () { [ "${BP_DEBUG}" = '1' ] && debug_message newline "curl ${curl_opts} -s -N \"https://gitlab.com/${1}/-/tags\"" "\n" local apk_tag="$(curl -A "${useragent}" -s -N "https://gitlab.com/${1}/-/tags" | grep -m1 ref-name | sed 's/.*\">//;s/<\/.*//')" local apk_url="$(curl -A "${useragent}" -s -N "https://gitlab.com/${1}/-/tags/${apk_tag}" | tr '<' '\n' | gawk -F \" '/uploads.*apk/{print $2}')" local apk_url="https://gitlab.com${apk_url}" local apk_dest="${appsfolder[2]}/${2}/${3}" download_apk_common "${apk_dest}" "${3}" "${apk_url}" gitlab } grab_apk_from_ogapps () { case "${4}" in 19 ) local api_letter=K ;; 21 ) local api_letter=L ;; 23 ) local api_letter=M ;; 24 ) local api_letter=N ;; 26 ) local api_letter=O ;; 28 ) local api_letter=P ;; 29 ) local api_letter=Q ;; 30 ) local api_letter=R ;; esac case "${1}" in "com.google.android.syncadapters.calendar" ) # use SDK 19 Calendar Syncadapter for SDK 19 # use SDK 21 Calendar Syncadapter for SDK 21 - 29 # use SDK 30 Calendar Syncadapter for SDK 30 if [ "${4}" -eq 19 ]; then local apk_url="${repo_ogapps}/all/raw/master/${2}/${1}/15/nodpi/2015080710.apk" elif [ "${4}" -eq 30 ]; then local apk_url="${repo_ogapps}/all/raw/master/${2}/${1}/30/nodpi/2017005136.apk" else local apk_url="${repo_ogapps}/all/raw/master/${2}/${1}/21/nodpi/2016267990.apk" fi ;; "com.google.android.syncadapters.contacts" ) local apk_url="${repo_ogapps}/all/raw/master/${2}/${1}/${4}/nodpi/${4}.apk" ;; "com.google.android.backuptransport" ) # Use SDK 28 Backuptransport on SDK 29 - 30 if [ "${4}" -ge 29 ]; then local apk_url="${repo_ogapps}/all/raw/master/${2}/${1}/28/nodpi/28.apk" else local apk_url="${repo_ogapps}/all/raw/master/${2}/${1}/${4}/nodpi/${4}.apk" fi ;; esac apk_dest="${appsfolder[6]}/${api_letter}/${2}/${3}" download_apk_common "${apk_dest}" "${3}" "${apk_url}" opengapps "${4}" } grab_lib_from_ogapps () { case "${3}" in arm | x86 ) LIBD=lib ;; arm64 | x86_64 ) LIBD=lib64 ;; esac local lib_url="${repo_ogapps}/${3}/raw/master/${LIBD}/${2}/${1}" local swp_dest="${appsfolder[8]}/${3}" if [[ "${4}" == "true" ]]; then local lib_dest="${swp_dest}/${1}_${2}" else lib_dest="${swp_dest}/${1}" fi if [[ -f "${lib_dest}" ]]; then echo -e "\nUpdating from OpenGApps : ${1} [${2}:${3}]" else echo -e "\nDownloading from OpenGApps: ${1} [${2}:${3}]" mkdir -p "${swp_dest}" fi echo " Checking SHA256 hash not (yet) supported" debug_download delete "${lib_dest}" "${lib_url}" "${lib_dest}" } grab_patches () { base_url="https://github.com/Lanchon/haystack/blob/master/patches" patch_url="${base_url}/${1}?raw=true" patch_dst="${CWD}/patcher/dexpatcher/${2}" echo -e "\nUpdating from Haystack : ${2}" echo " Checking SHA256 hash not (yet) supported" debug_download delete "${patch_dst}" "${patch_url}""${patch_dst}" }