borgend.py

Wed, 07 Feb 2018 20:39:01 +0000

author
Tuomo Valkonen <tuomov@iki.fi>
date
Wed, 07 Feb 2018 20:39:01 +0000
changeset 113
6993964140bd
parent 92
a1d3721ef5fa
permissions
-rwxr-xr-x

Time snapshot fixes.
Python's default arguments are purely idiotic (aka. pythonic): generated
only once. This makes sense in a purely functional language, which Python
lightyears away from, but severely limits their usefulness in an imperative
language. Decorators also seem clumsy for this, as one would have to tell
the number of positional arguments for things to work nice, being able to
pass the snapshot both positionally and as keyword. No luck.
So have to do things the old-fashioned hard way.

#!/usr/local/bin/python3
#
# Borgend by Tuomo Valkonen, 2018
#

# Common modules
import os
import sys
import argparse
import platform
import logging
# Own modules needed at this stage
import borgend.branding as branding
import borgend.locations as locations

#
# Argument processing
#

epilog_format="""
Configuration file location:

    %s

Log directory:

    %s/
 """

parser=argparse.ArgumentParser(
    description=branding.appname_stylised + ": BorgBackup scheduler, queue, and tray icon.",
    epilog=epilog_format % (locations.cfgfile, locations.logs_dir),
    formatter_class=argparse.RawDescriptionHelpFormatter)

parser.add_argument(
    '--no-tray',
    dest='notray',
    action='store_true',
    help='Do not show the tray icon')

parser.add_argument(
    '--debug',
    dest='debug',
    action='store_true',
    help='Set logging level to debug')

args=parser.parse_args()

#
# Done parsing args, import our own modules, and launch everything
#

import borgend.config as config
import borgend.dreamtime as dreamtime
import borgend.loggers as loggers
from borgend.scheduler import Scheduler
from borgend.repository import Repository
from borgend.backup import Backup

logger=loggers.mainlogger

if args.debug:
    logger.setLevel(logging.DEBUG)

tray = None
repos=[]
backups=[]

try:
    dreamtime.start_monitoring()

    scheduler = Scheduler()
    scheduler.start()

    repoconfigs=config.settings['repositories']

    logger.info('Initialising repositories')
    for i in range(len(repoconfigs)):
        r=Repository(i, repoconfigs[i])
        repos.append(r)

    backupconfigs=config.settings['backups']

    logger.info('Initialising backups')
    for i in range(len(backupconfigs)):
        b=Backup(i, backupconfigs[i], scheduler)
        backups.append(b)

    if args.notray or platform.system()!='Darwin':
        # Wait for scheduler to finish
        run=scheduler.join
    else:
        # This is needed for Ctrl+C to work.
        # TODO: proper exit handler, which seems to require
        # ditching/forking/extending rumps to extend the NSApp class
        from PyObjCTools.AppHelper import installMachInterrupt
        installMachInterrupt()
        # Start UI, and let it handle exit control
        from borgend.ui import BorgendTray
        tray=BorgendTray(backups);
        run=tray.run

    for r in repos:
        r.start()

    for b in backups:
        b.start()

    run()

except Exception as err:
    # TODO: Should write errors here to stderr;
    # perhaps add an extra stderr logger for error level messages
    logger.exception("Exception fell through: exiting")

finally:
    logger.debug("Exiting")

    for b in backups:
        b.terminate()

    for r in repos:
        r.terminate()

    if tray:
        tray.quit()
    else:
        logging.shutdown()

mercurial