Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.

Sun, 28 Jan 2018 11:38:01 +0000

author
Tuomo Valkonen <tuomov@iki.fi>
date
Sun, 28 Jan 2018 11:38:01 +0000
changeset 79
b075b3db3044
parent 78
83b43987e61e
child 80
a409242121d5

Cleaned up module organisation to simplify borgend.py and not have to import it in other modules.

backup.py file | annotate | diff | comparison | revisions
borgend.py file | annotate | diff | comparison | revisions
branding.py file | annotate | diff | comparison | revisions
config.py file | annotate | diff | comparison | revisions
dreamtime.py file | annotate | diff | comparison | revisions
instance.py file | annotate | diff | comparison | revisions
locations.py file | annotate | diff | comparison | revisions
loggers.py file | annotate | diff | comparison | revisions
repository.py file | annotate | diff | comparison | revisions
scheduler.py file | annotate | diff | comparison | revisions
ui.py file | annotate | diff | comparison | revisions
--- a/backup.py	Sun Jan 28 11:04:52 2018 +0000
+++ b/backup.py	Sun Jan 28 11:38:01 2018 +0000
@@ -5,7 +5,7 @@
 import config
 import logging
 import time
-import borgend
+import loggers
 import repository
 import dreamtime
 from enum import IntEnum
@@ -13,7 +13,7 @@
 from threading import Thread, Lock, Condition
 from scheduler import TerminableThread
 
-logger=borgend.logger.getChild(__name__)
+logger=loggers.get(__name__)
 
 JOIN_TIMEOUT=60
 
--- a/borgend.py	Sun Jan 28 11:04:52 2018 +0000
+++ b/borgend.py	Sun Jan 28 11:38:01 2018 +0000
@@ -1,174 +1,108 @@
 #!/usr/local/bin/python3
 
+# Common modules
 import os
 import sys
-import logging
-import logging.handlers
 import argparse
 import platform
-
-#
-# Branding
-#
-appname="borgend"
-appname_stylised="Borgend"
-
-#
-# Logging configuration
-#
-
-loglevel=logging.INFO
-logfmt="%(asctime)s:%(levelname)s:%(name)s:%(message)s"
-fifolog_capacity=1000
-fifolog_fmt="%(asctime)s:%(levelname)s:%(message)s"
-
-#
-# Setup logger, needed by the config module to be loaded next
-#
-
-logger=logging.getLogger(appname)
-logger.handlers.clear()
-logger.setLevel(loglevel)
-stderrlog=logging.StreamHandler()
-stderrlog.setLevel(logging.WARNING)
-logger.addHandler(stderrlog)
-logger.propagate=True
-
-#
-# Import our own modules. This needs to be done here
-# for the things above to be available to them
-#
-
-import config
-from scheduler import Scheduler
-from fifolog import FIFOHandler
-from repository import Repository
+import branding
+# Own modules needed at this stage
+import locations
 
 #
 # Argument processing
 #
 
-def do_args():
-    parser=argparse.ArgumentParser(
-        description=appname_stylised + ': BorgBackup scheduler and tray icon.',
-        epilog='Configuration file location:\n\n    %s\n ' % config.cfgfile,
-        formatter_class=argparse.RawDescriptionHelpFormatter)
+parser=argparse.ArgumentParser(
+    description=branding.appname_stylised + ": BorgBackup scheduler, queue, and tray icon.",
+    epilog='Configuration file location:\n\n    %s\n ' % locations.cfgfile,
+    formatter_class=argparse.RawDescriptionHelpFormatter)
 
-    parser.add_argument(
-        '--no-tray',
-        dest='notray',
-        action='store_true',
-        help='Do not show the tray icon')
+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')
+parser.add_argument(
+    '--debug',
+    dest='debug',
+    action='store_true',
+    help='Set logging level to debug')
 
-    return parser.parse_args()
+args=parser.parse_args()
 
 #
-# Main routine
+# Done parsing args, import our own modules, and launch everything
 #
 
-# First, setup our own logging handlers
-fifolog=FIFOHandler(fifolog_capacity)
-logger.addHandler(fifolog)
-fifolog.setFormatter(logging.Formatter(fifolog_fmt))
+import branding
+import config
+import dreamtime
+import loggers
+import logging
+from scheduler import Scheduler
+from repository import Repository
+from backup import Backup
 
-if __name__=="__main__":
-    # Parse args. Let argparse handle errors/exit if there are any
-    args= do_args()
-    tray = None
-    repos=[]
-    backups=[]
+logger=loggers.mainlogger
 
-    try:
-        args=do_args()
-
-        if args.debug:
-            logger.setLevel(logging.DEBUG)
-
-        if not os.path.isdir(config.logs_dir):
-            os.makedirs(config.logs_dir)
+if args.debug:
+    logger.setLevel(logging.DEBUG)
 
-        handler=logging.handlers.TimedRotatingFileHandler(
-            os.path.join(config.logs_dir, appname+'.log'),
-            when='D', interval=1)
-        handler.setFormatter(logging.Formatter(logfmt))
-        logger.addHandler(handler)
+tray = None
+repos=[]
+backups=[]
 
-        from threading import Thread
-        from backup import Backup
-        from queue import Queue
-        import signal, os
-        import dreamtime
+try:
+    dreamtime.start_monitoring()
 
-        dreamtime.start_monitoring()
+    scheduler = Scheduler()
+    scheduler.start()
 
-        scheduler = Scheduler()
-        scheduler.start()
-
-        repoconfigs=config.settings['repositories']
+    repoconfigs=config.settings['repositories']
 
-        for i in range(len(repoconfigs)):
-            logger.info('Setting up repository %d' % i)
-            r=Repository(i, repoconfigs[i])
-            repos.append(r)
+    for i in range(len(repoconfigs)):
+        logger.info('Setting up repository %d' % i)
+        r=Repository(i, repoconfigs[i])
+        repos.append(r)
 
-        backupconfigs=config.settings['backups']
+    backupconfigs=config.settings['backups']
 
-        for i in range(len(backupconfigs)):
-            logger.info('Setting up backup set %d' % i)
-            b=Backup(i, backupconfigs[i], scheduler)
-            backups.append(b)
-
-        for r in repos:
-            r.start()
-
-        for b in backups:
-            b.start()
+    for i in range(len(backupconfigs)):
+        logger.info('Setting up backup set %d' % i)
+        b=Backup(i, backupconfigs[i], scheduler)
+        backups.append(b)
 
-        if args.notray or platform.system()!='Darwin':
-            # Wait for scheduler to finish
-            scheduler.join()
-        else:
-            # Start UI, and let it handle exit control
-            from ui import BorgendTray
-            tray=BorgendTray(backups);
-            tray.run()
+    for r in repos:
+        r.start()
 
-    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 to outer level: exiting")
+    for b in backups:
+        b.start()
 
-    finally:
-        for b in backups:
-            b.terminate()
-
-        for r in repos:
-            r.terminate()
-
-        if tray:
-            tray.quit()
-        else:
-            logging.shutdown()
+    if args.notray or platform.system()!='Darwin':
+        # Wait for scheduler to finish
+        scheduler.join()
+    else:
+        # Start UI, and let it handle exit control
+        from ui import BorgendTray
+        tray=BorgendTray(backups);
+        tray.run()
 
-    #
-    # This shit is fucked, disables ^C etc., and threading doesn't seem to help
-    #
+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")
 
-    # ui_thread=Thread(target=tray.run)
-    # ui_thread.daemon=True
-    # ui_thread.start()
+finally:
+    for b in backups:
+        b.terminate()
 
-    # def quit_signal_handler(signum, frame):
-    #     print('Signal handler called with signal %s' % str(signum))
-    #     ui_thread.terminate()
-    #     os.exit()
+    for r in repos:
+        r.terminate()
 
-    # signal.signal(signal.SIGTERM, quit_signal_handler)
-    # signal.signal(signal.SIGINT, quit_signal_handler)
+    if tray:
+        tray.quit()
+    else:
+        logging.shutdown()
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/branding.py	Sun Jan 28 11:38:01 2018 +0000
@@ -0,0 +1,6 @@
+#
+# Branding
+#
+
+appname="borgend"
+appname_stylised="Borgend"
--- a/config.py	Sun Jan 28 11:04:52 2018 +0000
+++ b/config.py	Sun Jan 28 11:38:01 2018 +0000
@@ -10,9 +10,11 @@
 import logging
 import platform
 from functools import reduce
-import borgend
+import loggers
+import branding
+import locations
 
-logger=borgend.logger.getChild(__name__)
+logger=loggers.get(__name__)
 
 #
 # Defaults
@@ -39,20 +41,6 @@
 }
 
 #
-# Locations
-#
-
-if platform.system()!='Darwin':
-    import xdg
-    cfgfile=os.path.join(xdg.XDG_CONFIG_HOME, borgend.appname, "config.yaml")
-    logs_dir=os.path.join(xdg.XDG_DATA_HOME, borgend.appname, "logs")
-else:
-    import rumps
-    __base=rumps.application_support(borgend.appname)
-    cfgfile=os.path.join(__base, "config.yaml")
-    logs_dir=os.path.join(__base, "logs")
-
-#
 # Type checking etc.
 #
 
@@ -156,12 +144,12 @@
 
     return out
 
-if not (os.path.exists(cfgfile) and os.path.isfile(cfgfile)):
-    raise SystemExit("Configuration file required: %s" % cfgfile)
+if not (os.path.exists(locations.cfgfile) and os.path.isfile(locations.cfgfile)):
+    raise SystemExit("Configuration file required: %s" % locations.cfgfile)
 
-logger.info("Reading configuration %s missing" % cfgfile)
+logger.info("Reading configuration %s missing" % locations.cfgfile)
 
-with io.open(cfgfile, 'r') as file:
+with io.open(locations.cfgfile, 'r') as file:
     settings=expand_env(yaml.load(file), os.environ);
 
 #
--- a/dreamtime.py	Sun Jan 28 11:04:52 2018 +0000
+++ b/dreamtime.py	Sun Jan 28 11:38:01 2018 +0000
@@ -9,9 +9,9 @@
 import threading
 import weakref
 import datetime
-import borgend
+import loggers
 
-logger=borgend.logger.getChild(__name__)
+logger=loggers.get(__name__)
 
 _dreamtime_monitor=None
 
--- a/instance.py	Sun Jan 28 11:04:52 2018 +0000
+++ b/instance.py	Sun Jan 28 11:38:01 2018 +0000
@@ -5,11 +5,11 @@
 import json
 import logging
 import os
-import borgend
+import loggers
 from config import settings
 from subprocess import Popen, PIPE
 
-logger=borgend.logger.getChild(__name__)
+logger=loggers.get(__name__)
 
 necessary_opts=['--log-json', '--progress']
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/locations.py	Sun Jan 28 11:38:01 2018 +0000
@@ -0,0 +1,17 @@
+#
+# Locations
+#
+
+import os
+import platform
+import branding
+
+if platform.system()!='Darwin':
+    import xdg
+    cfgfile=os.path.join(xdg.XDG_CONFIG_HOME, branding.appname, "config.yaml")
+    logs_dir=os.path.join(xdg.XDG_DATA_HOME, branding.appname, "logs")
+else:
+    import rumps
+    __base=rumps.application_support(branding.appname)
+    cfgfile=os.path.join(__base, "config.yaml")
+    logs_dir=os.path.join(__base, "logs")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loggers.py	Sun Jan 28 11:38:01 2018 +0000
@@ -0,0 +1,61 @@
+#
+# Loggers
+#
+
+import os
+import logging
+import logging.handlers
+import atexit
+
+from fifolog import FIFOHandler
+import branding
+import locations
+
+#
+# Logging configuration
+#
+
+loglevel=logging.INFO
+logfmt="%(asctime)s:%(levelname)s:%(name)s:%(message)s"
+fifo_capacity=1000
+fifo_fmt="%(asctime)s:%(levelname)s:%(message)s"
+
+#
+# Setting up the main logger with fifo, stderr, and rotating files output
+#
+
+mainlogger=logging.getLogger(branding.appname)
+mainlogger.setLevel(loglevel)
+mainlogger.propagate=True
+
+mainlogger.handlers.clear()
+
+# Internal FIFO history
+fifo=FIFOHandler(fifo_capacity)
+fifo.setFormatter(logging.Formatter(fifo_fmt))
+mainlogger.addHandler(fifo)
+
+# stderr
+stderrlog=logging.StreamHandler()
+stderrlog.setLevel(logging.WARNING)
+mainlogger.addHandler(stderrlog)
+
+# Rotating files
+if not os.path.isdir(locations.logs_dir):
+    os.makedirs(locations.logs_dir)
+
+fileslog=logging.handlers.TimedRotatingFileHandler(
+    os.path.join(locations.logs_dir, branding.appname+'.log'),
+    when='D', interval=1)
+fileslog.setFormatter(logging.Formatter(logfmt))
+mainlogger.addHandler(fileslog)
+
+atexit.register(logging.shutdown)
+
+#
+# Routine for obtaining sub-loggers
+#
+
+def get(name):
+    return mainlogger.getChild(name)
+
--- a/repository.py	Sun Jan 28 11:04:52 2018 +0000
+++ b/repository.py	Sun Jan 28 11:38:01 2018 +0000
@@ -4,11 +4,11 @@
 
 import weakref
 import keyring
-import borgend
+import loggers
 import config
 from scheduler import QueueThread, QueuedEvent
 
-logger=borgend.logger.getChild(__name__)
+logger=loggers.get(__name__)
 
 class FIFOEvent(QueuedEvent):
     def __init__(self, cond, name=None):
--- a/scheduler.py	Sun Jan 28 11:04:52 2018 +0000
+++ b/scheduler.py	Sun Jan 28 11:38:01 2018 +0000
@@ -5,11 +5,11 @@
 #
 
 import time
-import borgend
+import loggers
 import dreamtime
 from threading import Condition, Lock, Thread
 
-logger=borgend.logger.getChild(__name__)
+logger=loggers.get(__name__)
 
 class QueuedEvent:
     def __init__(self, cond, name=None):
--- a/ui.py	Sun Jan 28 11:04:52 2018 +0000
+++ b/ui.py	Sun Jan 28 11:38:01 2018 +0000
@@ -5,15 +5,16 @@
 import rumps
 import time
 import datetime
-import logging
-import borgend
+import objc
+from threading import Lock, Timer
+
+import loggers
 import backup
 import dreamtime
-from threading import Lock, Timer
+import branding
 from config import settings
-import objc
 
-logger=borgend.logger.getChild(__name__)
+logger=loggers.get(__name__)
 
 traynames_ok={
     backup.State.INACTIVE: 'B.',
@@ -256,11 +257,10 @@
             logger.debug("Opening notification for error %s '%s'",
                          msgid, errorlog['message'])
 
-            notification_workaround(borgend.appname_stylised,
+            notification_workaround(branding.appname_stylised,
                                     msgid, errorlog['message'])
 
     def quit(self):
-        logging.shutdown()
         rumps.quit_application()
 
     def __menu_select_backup(self, sender, b):
@@ -270,7 +270,7 @@
             b.create()
         except Exception as err:
             logger.exception("Failure to initialise backup")
-            notification_workaround(borgend.appname_stylised,
+            notification_workaround(branding.appname_stylised,
                                     err.__class__.__name__, str(err))
 
 #

mercurial