File: android-deltas-sync/sync-changes-part2-phone.py
#!/data/data/com.termux/files/usr/bin/python3
#!/usr/bin/env python3 <= fails in Termux:Widget (see also _etc shims)
"""
=======================================================================
Sync Changes to Phone, Part 2: Phone
Run syncs whenever desired to propagate PC changes to the phone.
The phone will be updated only for modifications made on the PC.
See _README.html for license, attribution, version, and docs.
-----------------------------------------------------------------------
Usage:
Run this on your phone second (after running Part 1 on your PC), with:
python3 sync-changes-part2-phone.py
Run this from the Termux app's console, or any other app with a
console terminal. This file may also be run with no command line
from a Python IDE app (e.g., Pydroid 3 or QPython), and/or a
home-screen shortcut or widget (e.g., Termux:Widget).
Run this from any folder. It uses paths set in config_phone.py,
and finds that and common.py in its own folder automatically.
Step runtimes are shown in the console after step completion.
Step outputs go to files in LOGS; watch with 'tail -f LOGS/file'.
See _README.html for license, attribution, version, and docs.
-----------------------------------------------------------------------
Notes:
0) "PC" here means a Windows, macOS, or Linux device, but "phone"
can be anything: though designed to sync changes to Android 11 and
later, these scripts can also sync to earlier Androids and PCs.
1) Heritage: this is a Python translation of a same-named Bash
script in folder _etc/bash-version/; hence the too-many globals.
Translated for Windows portability: Cygwin and WSL have seams.
The Bash originals more explicitly show command lines run here.
=======================================================================
"""
import os, sys, shutil
from os.path import join
import config_phone, common # get phone settings and common code
common.startup(config_phone, common) # copy and use phone config's settings
from common import * # use both's top-level names as globals
# subjects
thezip = join(FROM, 'DELTAS.zip') # where user copies zipfile on phone
thedlt = join(FROM, 'DELTAS') # what the unzip creates on phone
thedst = join(TO, STUFF) # where deltas are applied on phone
# 'to' must exist here
if not os.path.isdir(thedst):
print('The TO/STUFF folder does not exist: "%s"' % thedst)
print('Exiting; please check the config file and rerun.')
shutdown(bad=True)
opener('Syncing:\nfrom %s\nto %s\nlogs %s' % (thezip, thedst, LOGS))
#----------------------------------------------------------------
# 1) Copy deltas zip from proxy to phone with an explorer app
#----------------------------------------------------------------
# Choose your app (but not Termux: POSIX cannot access USB in 11)
msg = """
Manually copy or move DELTAS.zip
from the root of the USB drive
to %s
using any Android file-explorer app with suitable storage permissions.
""" % FROM
print(msg)
input('Press enter/return here when the copy is finished...')
# did the copy work?
if not os.path.exists(thezip):
print('Deltas zip not found at "%s"' % thezip)
print('Please rerun this script to try again.')
shutdown(bad=True)
#----------------------------------------------------------------
# 2) Unzip deltas on phone with [zip-extract.py] in Termux
#----------------------------------------------------------------
announce('Unzipping deltas on phone')
logto = join(LOGS, '%s--sync-1-unzip-deltas-log.txt' % DATE)
# for a deltas tree not deleted by last run: delete, iff approved
removeExistingOrStop(thedlt, 'phone (DELTAS)')
# perms may disable updates in app-specific storage
permissions = ('-permissions',) if UnixPermissions else ()
runpy(join(ZIP, 'zip-extract.py'),
thezip, FROM, *permissions, # makes FROM/DELTAS == thedlt
logpath=logto,
tailing=(1, 'Zip extract summary'))
#----------------------------------------------------------------
# 3) Apply deltas to phone with [mergeall.py -restore] in Termux
#----------------------------------------------------------------
announce('Applying deltas to phone')
logto = join(LOGS, '%s--sync-2-apply-deltas-log.txt' % DATE)
# backup phone changes? (__bkp__ prunes slow in shared storage)
backup = ('-backup',) if BackupChanges else ()
runpy(join(MALL, 'mergeall.py'),
thedlt, thedst, '-restore', '-auto', '-skipcruft', *backup, '-quiet',
logpath=logto,
tailing=(9, 'Mergeall summary'))
#----------------------------------------------------------------
# 4) Cleanup deltas zip and folder on phone in Termux
#----------------------------------------------------------------
print('Removing deltas folder from phone')
timefunc(lambda: rmtree_FWP(thedlt, required=False))
# on-phone zip; user may have copied or moved the proxy zip, but can't check here
print('Removing deltas zip from phone (remove manually from proxy as needed)')
timefunc(lambda: os.remove(thezip))
#----------------------------------------------------------------
# Configurable: hook for custom post-propagate steps
#----------------------------------------------------------------
import z_postcopy_hook_phone # no need for runpy() in __file__ here
closer('See logs in "%s".' % LOGS)