PYTHON_VERSION="3.15"
#
# Customization script for the Magisk Module with python3
#
# History
#   10.04.2025 /bs
#     initial release
#   09.10.2025 /bs
#     added the directory usr/share to the list of directories for which the permissions must be changed
#   07.11.2025 /bs
#     added the variable PYTHON_VERSION for the python version
#
# Notes:
#
# This Magisk Module contains files for arm64 CPUs
#
# Documentation for creating Magisk Modules: https://topjohnwu.github.io/Magisk/guides.html
#
# Environment variables that can be used:
#
#    MAGISK_VER (string): the version string of current installed Magisk (e.g. v20.0)
#    MAGISK_VER_CODE (int): the version code of current installed Magisk (e.g. 20000)
#    BOOTMODE (bool): true if the module is being installed in the Magisk app
#    MODPATH (path): the path where your module files should be installed
#    TMPDIR (path): a place where you can temporarily store files
#    ZIPFILE (path): your module’s installation zip
#    ARCH (string): the CPU architecture of the device. Value is either arm, arm64, x86, or x64
#    IS64BIT (bool): true if $ARCH is either arm64 or x64
#    API (int): the API level (Android version) of the device (e.g. 21 for Android 5.0)
#

# -----------------------------------------------------------------------------

# define constants
#
__TRUE=0
__FALSE=1

if [ 0 = 1 -o -r /data/local/tmp/debug ] ; then
  ui_print "Writing all messages to the log file /data/local/tmp/python_customize.log"	
  exec 1>/data/local/tmp/python_customize.log 2>&1
  set -x
fi

tty -s && RUNNING_IN_TERMINAL=${__TRUE} || RUNNING_IN_TERMINAL=${__FALSE}

# -----------------------------------------------------------------------------
# init global variables
#

MODULE_VERSION="$( grep "^version=" $MODPATH/module.prop  | cut -f2 -d "=" )"

MODULE_NAME="$( grep "^name=" $MODPATH/module.prop  | cut -f2 -d "=" )"

CMD_PARAMETER=""

MODULE_DESC="${MODULE_NAME} ${MODULE_VERSION}"

HOME_DIR="/data/local/tmp/home"

# directory for site-packages for all python versions
# 
GENERAL_SITE_PACKAGES_DIR="${HOME_DIR}/python/site-packages"

# directory for site-packages for Python 
#
PYTHON_VERSION_SITE_PACKAGES_DIR="${HOME_DIR}/python${PYTHON_VERSION}/site-packages"

# directory for the compiled python files
#
PYTHONPYCACHEPREFIX="${HOME_DIR}/python/cache"

# certificate bundle file
# 
CERTIFICATE_BUNDLE_FILE="${HOME_DIR}/ca-certificates.crt"

# -----------------------------------------------------------------------------

function LogMsg {
  ui_print "$*"
}

function LogInfo {
  LogMsg "INFO: $*"
}

function LogWarning {
  LogMsg "WARNING: $*"
}

function LogError {
  LogMsg "ERROR: $*"
}


# -----------------------------------------------------------------------------

LogMsg "The current environment for this installation is"

LogMsg "The version of the installed Magisk is \"${MAGISK_VER}\" (${MAGISK_VER_CODE})"

LogInfo "BOOTMODE is \"${BOOTMODE}\" "
LogInfo "MODPATH is \"${MODPATH}\" "
LogInfo "TMPDIR is \"${TMPDIR}\" "
LogInfo "ZIPFILE is \"${ZIPFILE}\" "
LogInfo "ARCH is \"${ARCH}\" "
LogInfo "IS64BIT is \"${IS64BIT}\" "
LogInfo "API is \"${API}\" "

# -----------------------------------------------------------------------------

# example output for the variables:


#  The version of the installed Magisk is "25.0" (25000)
#  INFO: BOOTMODE is "true" 
#  INFO: MODPATH is "/data/adb/modules_update/PlayStore_for_MicroG" 
#  INFO: TMPDIR is "/dev/tmp" 
#  INFO: ZIPFILE is "/data/user/0/com.topjohnwu.magisk/cache/flash/install.zip" 
#  INFO: ARCH is "arm64" 
#  INFO: IS64BIT is "true" 
#  INFO: API is "32"


# -----------------------------------------------------------------------------

LogMsg "Installing the Magisk Module with ${MODULE_NAME} for Android \"${MODULE_VERSION}\" ..."

LogMsg "Checking the OS configuration ..."

ERRORS_FOUND=${__FALSE}

MACHINE_TYPE="$( uname -m )"

# check the current CPU
#
LogMsg "Checking the type of the CPU used in this device ...."

LogMsg "The CPU in this device is a ${ARCH} CPU"
LogMsg "The machine type reported by \"uname -m\" is \"${MACHINE_TYPE}\" "


if [ "${ARCH}"x != "arm64"x ] ; then
  abort "This Magisk module is for arm64 CPUs only"
fi


# ---------------------------------------------------------------------

# create the home directory if it does not yet exist
# 
if [ ! -d "${HOME_DIR}" ] ; then
  echo "Creating the directory \"${HOME_DIR}\" ..."
  mkdir -p "${HOME_DIR}" && \
    chmod 755 "${HOME_DIR}" && \
    chown shell:shell "${HOME_DIR}"
fi

# create the SSL ceritifcate bundle file
#
if [ ! -r ${CERTIFICATE_BUNDLE_FILE} ] ; then
  LogMsg "Creating the file \"${CERTIFICATE_BUNDLE_FILE}\" ..."

  ls -l /system/etc/security/cacerts*/*.0 2>/dev/null 1>/dev/null
  if  [ $? -ne 0 ] ; then
    LogWarning "No certificates found in the directories \"/system/etc/security/cacerts*\" -- can not create the bundle file \"${CERTIFICATE_BUNDLE_FILE}\" "
  else
    for i in  ${SYSROOT_DIR}/etc/security/cacerts*/*.0 ; do
      [ ${RUNNING_IN_TERMINAL}x = ${__TRUE}x ] && printf "."
      echo "$(sed -n "/BEGIN CERTIFICATE/,/END CERTIFICATE/p" $i)" >>"${CERTIFICATE_BUNDLE_FILE}"
    done
    [ ${RUNNING_IN_TERMINAL}x = ${__TRUE}x ] &&  printf "\n"
    LogMsg "... done:"
    LogMsg ""
    ls -l "${CERTIFICATE_BUNDLE_FILE}"
    LogMsg ""
  fi
else
  LogMsg "The certificate bundle file \"${CERTIFICATE_BUNDLE_FILE}\" already exists:"
  LogMsg ""
  LogMsg "$( ls -l "${CERTIFICATE_BUNDLE_FILE}" )"
  LogMsg ""
fi

for CUR_SITE_PACKAGES_DIR in "${PYTHON_VERSION_SITE_PACKAGES_DIR}"  "${GENERAL_SITE_PACKAGES_DIR}" "${PYTHONPYCACHEPREFIX}"; do
  if [ ! -d "${CUR_SITE_PACKAGES_DIR}" ] ; then
    LogMsg "Creating the directory \"${CUR_SITE_PACKAGES_DIR}\" ..."
    mkdir -p "${CUR_SITE_PACKAGES_DIR}" && \
      chown shell:shell "${CUR_SITE_PACKAGES_DIR}" && \
        chmod 755 "${CUR_SITE_PACKAGES_DIR}"
  else 
    LogMsg "The directory \"${CUR_SITE_PACKAGES_DIR}\" already exists"
  fi
done

# add the writable site-packages directories to the list of known site-packages directories for Python if not already done
# 
for CUR_SITE_PACKAGES_DIR in "${PYTHON_VERSION_SITE_PACKAGES_DIR}"  "${GENERAL_SITE_PACKAGES_DIR}" ; do
  grep "${CUR_SITE_PACKAGES_DIR}" ${MODPATH}/system/usr/lib/python${PYTHON_VERSION}/site-packages/local_tmp.pth 2>/dev/null 1>/dev/null
  if [ $? -ne 0 ] ; then
    echo "${CUR_SITE_PACKAGES_DIR}" >>${MODPATH}/system/usr/lib/python${PYTHON_VERSION}/site-packages/local_tmp.pth
  fi
done

# create the symoblic link for python if it's missing
# 
if [ ! -r "${MODPATH}/system/usr/bin/python" ] ; then
  ln -s ./python3 "${MODPATH}/system/usr/bin/python"
fi

LogMsg "Correcting the permissions for the new files ..."

# first usr/* then bin, lib  etc !
# 
for i in etc include usr/include usr/lib usr/share  ; do

  [[ $i != /\* ]] && CUR_ENTRY="${MODPATH}/system/$i" || CUR_ENTRY="$i"

  [ ! -d "${CUR_ENTRY}" ] && continue

  LogMsg "Processing the files in the directory ${CUR_ENTRY} ..."
  set_perm_recursive "${CUR_ENTRY}" 0 0 0755 0644 u:object_r:system_file:s0
  chcon -R -h u:object_r:system_file:s0 "${CUR_ENTRY}"
done

for i in bin lib lib64 usr/bin  ; do
  [ ! -d "${MODPATH}/system/$i" ] && continue
  LogMsg "Processing the files in the directory ${MODPATH}/system/$i ..."

  set_perm_recursive "${MODPATH}/system/$i" 0 0 0755 0755 u:object_r:system_file:s0

  chcon -R -h  u:object_r:system_file:s0 "${MODPATH}/system/$i"
done

