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)



[Home page] Books Code Blog Python Author Train Find ©M.Lutz