File: android-deltas-sync/initial-copy-part1-pc.py
#!/usr/bin/env python3 """ ======================================================================= Initial Copy to Phone, Part 1: PC Run initial copies once, to propagate full content from PC to phone. Later, run syncs to propagate just changes to the phone on demand, and phone verifies and exports as desired. See _README.html for license, attribution, version, and docs. ----------------------------------------------------------------------- Usage: Run this on your PC first (before running Part 2 on your phone), with: python3 initial-copy-part1-pc.py Run this in Terminal on macOS and Linux; and in Command Prompt, PowerShell, Cygwin, or WSL on Windows. Replace its "python3" with "python" where needed, and "py -3" in basic Windows shells. This file may also be run with no command line by click or IDE. Run this from any folder. It uses paths set in config_pc.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) 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. 2) Design: this keeps the content zip on the PC as long as possible for speed; it's still on PC for the to-proxy unzip. This may be trivial for fast SSDs, but USB is still slower. 3) Design: step 2 could use Mergeall's cpall.py instead of ziptools' zip-extract.py; both copy from PC to proxy drive. In testing, however, a 210G content folder of 180k items copied from PC to SSD in 14 minutes with cpall, but just under 13 minutes with zip-extract when the zipfile is on PC. Hence, unzipping is faster, most likely because it opens just one input file, the zip; cpall must open 180k. 4) Times: this Python version allows runtimes to be configured on or off with ShowRuntimes. This wasn't supported in the Bash original, because a simple time=(time|'') and $time invokes a different time. Bash starts to break down at this point. 5) Coding: to shorten paths in zipfiles and hence on unzips, this can either os.chdir to content folders, or use ziptools' '-zip@.' arg to strip the path leading to the zipped item. The former shortens ziptools output, but its state is tricky. 6) Caveat: this script requires space for both content and its uncompressed zip on the proxy - essentially twice the size of content. If space is tight, manually move the zip to the phone, before copying content to the proxy drive. ======================================================================= """ import os, sys, shutil from os.path import join import config_pc, common # get PC settings and common code common.startup(config_pc, common) # copy and use PC config's settings from common import * # use both's top-level names as globals # subjects TOroot = driveRootPath(TO) thesrc = join(FROM, STUFF) # where content is on PC thezip = join(FROM, STUFF) + '.zip' # what the zip makes on PC thedst = join(TO, STUFF) # where content goes on proxy prxzip = join(TOroot, STUFF) + '.zip' # where zip is copied on proxy # 'from' must exist here if not os.path.isdir(thesrc): print('The FROM/STUFF folder does not exist: "%s"' % thesrc) print('Exiting; please check the config file and rerun.') shutdown(bad=True) opener('Copying:\nfrom %s\nto %s\nzip %s\nlogs %s' % (thesrc, thedst, prxzip, LOGS)) #---------------------------------------------------------------- # Optional: offer to run nonportable-filenames fixer tool #---------------------------------------------------------------- offerFixnamesRun('init-0', target=thesrc) #---------------------------------------------------------------- # 1) Zip PC content with [zip-create.py -nocompress], store on PC #---------------------------------------------------------------- announce('Zipping content on PC') logto = join(LOGS, '%s--init-1-pc-zip-log.txt' % DATE) runpy(join(ZIP, 'zip-create.py'), thezip, thesrc, '-zip@.', '-skipcruft', '-nocompress', logpath=logto, tailing=(1, 'Zip create summary')) #---------------------------------------------------------------- # 2) Unzip from PC to proxy with [zip-extract.py]: phone stand-in #---------------------------------------------------------------- announce('Unzipping content on proxy') logto = join(LOGS, '%s--init-2-proxy-unzip-log.txt' % DATE) # delete an existing content tree, iff approved removeExistingOrStop(thedst, 'proxy') # MALL/cpall.py is slower (see above), always save perms in zip (not phone) runpy(join(ZIP, 'zip-extract.py'), thezip, TO, '-permissions', # makes TO/STUFF == thedst logpath=logto, tailing=(1, 'Zip extract summary')) #---------------------------------------------------------------- # 3) Move zip from PC to proxy: phone copy #---------------------------------------------------------------- # copy and delete the content zip # or: zip to proxy in step 1 and skip step 3, but PC likely net faster announce('Moving content zip to proxy') timefunc(lambda: moveZipToProxy(thezip, prxzip)) #---------------------------------------------------------------- # Optional: verify content copied from PC to phone #---------------------------------------------------------------- verifyPCtoProxy('init-3', 'init-4') # mergeall/diffall log names closer('See logs in "%s", and run part 2 on your phone.' % LOGS)