File: android-deltas-sync/x-verify-phone-part1-phone.py
#!/data/data/com.termux/files/usr/bin/python3
#!/usr/bin/env python3 <= fails in Termux:Widget (see also _etc shims)
"""
=======================================================================
Verify Phone Content, Part 1: Phone [new in 1.1]
Run verifications occasionally (if ever) to prove that the on-phone
content copy matches that on the PC; it's a useful but slow process.
Verify scripts can also be used to export phone content to a PC,
but may require a manual PC copy and proxy sync. As of 1.2, the
new x-export-* scripts perform fully-automated exports to both PC
and proxy, and are recommended for most phone-to-PC export roles.
As of 1.2, this script is used as the on-phone part-1 step of both
verifies and exports.
See _README.html for license, attribution, version, and docs.
-----------------------------------------------------------------------
Usage:
Run this on your phone first (before running Part 2 on your PC), with:
python3 x-verify-phone-part1-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 commmon.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'.
-----------------------------------------------------------------------
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) You can run the zip and manual-move steps here manually;
this script is simply a convenience that automates the steps and
follows the rest of this package's motif, with error/safety checks.
2) This uses the phone config's settings unchanged, but inverts
their meaning: "TO" (the on-phone copy) is really FROM here (it's
what is zipped), and "FROM" is assumed to be usable for creating
the zip (and should be optimal: use app storage instead of shared
storage for much faster zips).
3) Caveat: verification makes a full-content zipfile on the phone,
which is then moved to the proxy drive and unzipped on the PC.
Hence, you'll need _twice_ the size of full content on all three
devices. This is unavoidable without on-phone POSIX USB access.
4) This uses _uncompressed_ zips for speed; the space savings for
compression is minimal, and won't help much with the preceding note.
5) As of 1.2, this file's code is now also used for part 1 of the
export procedure, since it's identical (both simply zip the phone's
content in full and prompt for a manual copy to proxy). See the
export part 1 script's Dev notes for more on the reuse (hack).
6) As of 1.2, this was renamed from "verify..." to "x-verify..."
because it's a lesser and optional tool, and so that it appears at
the end of by-name folder listings. Exports are named similarly.
=======================================================================
"""
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
thesrc = join(TO, STUFF) # where content is on phone
thezip = join(FROM, 'PHONE.zip') # where to zip on-phone content on phone
# 'from' must exist here
if not os.path.isdir(thesrc):
print('The TO/STUFF on-phone content folder does not exist: "%s"' % thesrc)
print('Exiting; please check the config file and rerun.')
shutdown(bad=True)
# FROM is checked for isdir() in common.py
# Hack to reuse this code for exports: see x-export-phone-part1-phone.py
MODE = 'Export' if globals().get('EXPORTING') else 'Verify'
opener('%sing:\nfrom %s\nzip %s\nlogs %s' % (MODE, thesrc, thezip, LOGS))
#----------------------------------------------------------------
# Optional: for exports, offer to run nonportable-filenames fixer
#----------------------------------------------------------------
# Though rare, names created in Android app storage may fail on Windows
if MODE == 'Export':
offerFixnamesRun('export-0', target=thesrc)
#----------------------------------------------------------------
# 1) Zip phone content on phone with [zip-create.py -nocompress]
#----------------------------------------------------------------
# This silently blows away an existing zipfile, but all zips here do
announce('Zipping content on phone')
logto = join(LOGS, '%s--%s-1-phone-zip-log.txt' % (DATE, MODE.lower()))
runpy(join(ZIP, 'zip-create.py'),
thezip, thesrc, '-zip@.', '-skipcruft', '-nocompress',
logpath=logto,
tailing=(1, 'Zip create summary'))
#----------------------------------------------------------------
# 2) Copy verify zip from phone to proxy with an explorer app
#----------------------------------------------------------------
# Choose your app (but not Termux: POSIX cannot access USB in 11)
msg = """
Manually move PHONE.zip
from %s
to the root of the USB drive
using any Android file-explorer app with suitable storage permissions.
""" % FROM
# wait for reply: include copy time in elapsed, and offer to remove
print(msg)
input('Press enter/return here when the move is finished...')
# did the move work?
if os.path.exists(thezip):
userreply = input('%s zip still exists on phone: remove it now (y or n)?' % MODE)
if userreply == 'y':
timefunc(lambda: os.remove(thezip))
# cannot verify the move's USB desination here: check in step 2 on the PC
closer('See logs in "%s", and run part 2 on your PC.' % LOGS)