File: thumbspage/build/

#!/usr/bin/env python3
Add analytics code to online resources before they are uploaded [2.1].
Part of the thumbspage program (

This script was recoded to support two usage modes:

1) Add analytics to all thumbspage resources (original)
2) Add analytics to any single file (new)

The first mode is invoked with zero command-line arguments, as before. 
The second is invoked with a pathname, and used by external-demo builds.
The second mode is not thumbspage specific, but reuses its common code.
The second mode can also be used by importing its function from here.

For both modes:

Works by replacing comment keys in files: see 'replacekeys' list below.
Makes no changes to files that already have analytics (e.g., reruns).
Note that analytics could be left in resources always, because it's not
run when docs are viewed locally via file:// URLs; omitted for courtesy. 

Analytics is anonymized (IPs are truncated), and is used only for 
prioritizing website development.  For more, see the website's
privacy statement:

For mode 1:

Run me from anywhere: always changes to the website-publishing folder.
Inserts analytics code in the online versions of the user guide and all 
example-gallery index pages.  This does not add analytics to individual 
images' _viewer_ pages in a gallery (even though they have the same key 
as default index headers, replace1 ahead); that seems too much data.

This automates roughly 20 file edits every time thumbspage is released.
To use it elsewhere, change folder paths, and possibly replacement keys.
import os, sys

# This will naturally vary per site (don't use this verbatim!)

analytics = """
<!-- anonymous analytics to prioritize work: enabled in online resources only -->
  // Start async JavaScript-file fetch, if not already cached

  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),

  // Queue actions to run in order after async JS-file fetch finished

  ga('create', 'UA-52579036-1', 'auto');       // Create tracker object (and queue)
  ga('set', 'anonymizeIp', true);              // Anonymize IP addr (&aip) [Jun-2019]
  ga('send', 'pageview');                      // Send page-view event now 

# Analytics may be formatted arbitrarily if already present: look for this

analyticskey = "ga('send', 'pageview')"

# Replacement keys - change or pass as needed to use this script elsewhere:
# - replace1: auto-added by thumbspage in default headers <head> since 2.0 
# - replace2: inserted manually in custom headers over the years before 2.0
# And some examples have analytics already present; this was < consistent, 
# but legacy.  replace1 is also auto-added to viewer pages' <head> by 2.0+,
# but viewer pages on this site never have analytics inserted (it's TMI).
# Caution: files with just commented-out analytics must be changed to use 
# a tag instead, else they will be skipped as already having analytics.
# This is also legacy, from manual procedures that uncommented code; alas.

replace1 = '<!-- Plus analytics code, custom styles, etc. (replace me) -->'
replace2 = '<!-- plus analytics code, etc. -->'
replacekeys = [replace1, replace2]

# Paths used for mode 2 (thumbspage): change|pass to use script elsewhere

homedir = os.environ['HOME']
codedir = homedir + '/MY-STUFF/Code/thumbspage'
pubdir  = homedir + '/MY-STUFF/Websites/Programs/Current/Complete/thumbspage'

def insertOneFile(filepath, replacekeys=replacekeys, trace=print):
    Insert analytics code at any replacement key in filepath, in place.
    This can be used for any site file, not just thumbspage examples.
    changed = False
    filetext = open(filepath, 'r', encoding='utf8').read()
    if analyticskey in filetext:
        trace('File already has analytics:', filepath) 

    elif not any(key in filetext for key in replacekeys):
        trace('File lacks replacement key:', filepath)

        changed = True
        replace = [key for key in replacekeys if key in filetext]
        filetext = filetext.replace(replace[0], replace[0] + analytics)

        fileout = open(filepath, 'w', encoding='utf8')
        fileout.close()  # flush for diff or other

        replaceindexes = [replacekeys.index(key) for key in replace]
        trace('Inserted analytics in file: '
              'keys=%s, file=%s' % (replaceindexes, filepath))
        if len(replace) > 1:
            trace('caution'.upper() + ': multiple replacement keys in file')

    return changed

def insertThumbspageExamples(pubdir, codedir, verbose=False):
    Insert analytics code into user guide and all thumbspage examples.
    Run just before uploads, works on the website publication folder.
    os.chdir(pubdir)    # thumbspage upload copy

    # user guide
    ugname = 'UserGuide.html'
    changed = insertOneFile(ugname)

    if changed and verbose:
        print('Diff of new user guide to original:')
        os.system('diff %s %s/%s' % (ugname, codedir, ugname))

    # example indexes
    numexchanged = 0
    for (dirhere, subshere, fileshere) in os.walk('examples'):
        for name in fileshere:
            if name == 'index.html':
                expath = os.path.join(dirhere, name)
                changed = insertOneFile(expath)

                if changed:
                    numexchanged += 1
                    if verbose:
                        print('Diff of new example index to original:')
                        os.system('diff %s %s/%s' % (expath, codedir, expath))

    print('Examples changed:', numexchanged)

if __name__ == '__main__':
    if len(sys.argv) == 1:
        insertThumbspageExamples(pubdir, codedir)    # no args: all thumbspage files

    elif len(sys.argv) == 2:
        insertOneFile(sys.argv[1])                   # one arg: this specific file only 

        print('Usage: python3 singleFilePath?')    

Example output (none are inserted on reruns):

Inserted analytics in file: keys=[1], file=UserGuide.html

Inserted analytics in file: keys=[1], file=examples/Screenshots/index.html

Inserted analytics in file: keys=[1], file=examples/1.7-upgrades/index.html

Inserted analytics in file: keys=[0], file=examples/unicode/images/index.html

Inserted analytics in file: keys=[1], file=examples/dynamiclayout/index.html

File already has analytics: examples/dynamiclayout/Demo-Wide-Filename-Labels/index.html

File already has analytics: examples/dynamiclayout/Demo-Narrow-Filename-Labels/index.html

Inserted analytics in file: keys=[1], file=examples/reorientation/index.html

File already has analytics: examples/reorientation/Unrotated-images-in-browsers/index.html

Inserted analytics in file: keys=[0], file=examples/mixedtypes/index.html

Inserted analytics in file: keys=[0], file=examples/mixedtypes/Limited-Support-Types/index.html

Inserted analytics in file: keys=[0], file=examples/subfolders/index.html

Inserted analytics in file: keys=[0], file=examples/subfolders/Subfolder3/index.html

Inserted analytics in file: keys=[0], file=examples/subfolders/Subfolder2/index.html

Inserted analytics in file: keys=[0], file=examples/subfolders/Subfolder1/index.html

Inserted analytics in file: keys=[0], file=examples/subfolders/Subfolder1/SubSubfolder/index.html

Inserted analytics in file: keys=[1], file=examples/2.1-upgrades/index.html

Inserted analytics in file: keys=[1], file=examples/2.0-upgrades/index.html

Inserted analytics in file: keys=[0], file=examples/2.0-upgrades/MORE-INFO-POPUP/index.html
Examples changed: 15

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