borgend.py

Sun, 05 Dec 2021 00:42:01 +0200

author
Tuomo Valkonen <tuomov@iki.fi>
date
Sun, 05 Dec 2021 00:42:01 +0200
changeset 133
ec8014a2ee7a
parent 92
a1d3721ef5fa
permissions
-rwxr-xr-x

Need to time menu updates using Apple's frameworks to avoid segfaults.
However rumps.Timer doesn't work with menu updates while the menu is open, so
implement EventTrackingTimer class that uses NSEventTrackingRunLoopMode in
mainRunLoop.

#!/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