#!/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)