changeset 20:5c5edfb827b7

more the things
author Jeff Hammel <k0scist@gmail.com>
date Thu, 16 Jan 2014 04:29:39 -0800
parents 54e9c335e239
children da4848140985
files setup.py silvermirror/config.py silvermirror/unify.py
diffstat 3 files changed, 98 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/setup.py	Fri Jul 05 08:07:48 2013 -0700
+++ b/setup.py	Thu Jan 16 04:29:39 2014 -0800
@@ -1,19 +1,19 @@
 from setuptools import setup, find_packages
 
-version = '0.2'
+version = '0.2.1'
 
 setup(name='silvermirror',
       version=version,
       description="mirror files across hosts",
       long_description="""\
 """,
-      classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[],
       keywords='mirror unison',
       author='Jeff Hammel',
       author_email='k0scist@gmail.com',
       url='http://explosivedecompression.net',
       license='GPL',
-      packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
+      packages=['silvermirror'],
       include_package_data=True,
       zip_safe=False,
       install_requires=[
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/silvermirror/config.py	Thu Jan 16 04:29:39 2014 -0800
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+
+import optparse
+import os
+import sys
+
+from .utils import home
+from martini.config import ConfigMunger
+
+class SilvermirrorConfiguration(object):
+    """
+    SilverMirror configuration class
+
+    The current form is an .ini file
+    [TODO: use `install_requires='configuration'`]:
+
+    [::SilverMirror::]
+    ...
+    """
+
+    main_section = '::SilverMirror::'
+
+    def __init__(self, filename=None):
+        if filename is not None:
+            self.read_config(filename)
+    def read_config(self, filename):
+
+        # read file
+        config = ConfigMunger(filename).dict()
+
+        # main configuration
+        main = config.pop(, {})
+        main.setdefault('basedir', home())
+        main['ignore'] = main.get('ignore', '').split() # patterns to ignore - 
+        main['hosts'] = main.get('hosts', '').split()
+        main['timeout'] = float(main.get('timeout', '10.'))
+
+        # password prompt
+        truth = dict([(str(i).lower(), i) for i in (True, False)])
+        password = main.get('password', 'true')
+        try:
+            main['password'] = truth[password.lower()]
+        except KeyError:
+            raise KeyError("password must be True or False (You gave: '%s')" % password)
+
+        # resources
+        for resource in config:
+
+            # directory of resource
+            directory = config[resource].get('directory', resource)
+            if os.path.isabs(directory):
+                raise NotImplementedError("absolute directories will not work for now so....don't do this!")
+
+            else:
+                directory = os.path.join(main['basedir'], directory)
+            config[resource]['directory'] = directory.rstrip(os.path.sep)
+
+            # per-resource files to ignore
+            # XXX  regexps for now (see `man unison`)
+            # - this is bad as whitespace patterns cannot be ignored
+            config[resource]['ignore'] = main['ignore'][:] + config[resource].get('ignore', '').split()
+
+    # set + return ditionary of config
+    self.main = main
+    self.resources = config
+    config = (main, config)
+
+def main(args=sys.argv[1:]):
+
+    usage = '%prog [options]'
+    parser = optparse.OptionParser(usage=usage, description=__doc__)
+    options, args = parser.parse_args(args)
+
+if __name__ == '__main__':
+    main()
--- a/silvermirror/unify.py	Fri Jul 05 08:07:48 2013 -0700
+++ b/silvermirror/unify.py	Thu Jan 16 04:29:39 2014 -0800
@@ -17,6 +17,7 @@
     # XXX needed?
     raise NotImplementedError('Need to specify a config file, like\n~/silvermirror/silvermirror.ini')
 
+
 def read_config(filename):
     config = ConfigMunger(filename).dict()
 
@@ -59,15 +60,18 @@
     config = { 'main': main, 'resources': config }
     return config
 
-def unify(conf, _resources, test=False):
+def unify(conf, _resources, test=False, verbose=True, notification_prefix='\n*** SilverMirror; '):
+    # TODO: -> OO
+
+    # log function
+    def log(message):
+        if verbose:
+            print ("%s%s" % (notification_prefix, message))
 
     # passwords
     pw = {}
 
-    # XXX needed for now
-    assert conf['main']['basedir'] == home()
-
-    ### determine hosts to sync with
+    # determine hosts to sync with
     hosts = conf['hosts']
     addresses = ip_addresses().values()
     hosts = hosts.difference(addresses) # don't sync with self
@@ -84,11 +88,9 @@
             continue
         _hosts.append(host)
     hosts = _hosts
-    if test:
-        print 'Hosts:'
-        for host in hosts:
-            print host
-    assert hosts
+    log("Hosts:\n%s" % '\n'.join(hosts))
+    if not hosts:
+        raise AssertionError("No hosts specified")
 
     if conf['main']['password']:
         for host in hosts:
@@ -110,7 +112,7 @@
                     resources = { key: value }
                     break
     if test:
-        print 'Resources:'
+        log("Resources:\n%s")
         pprint(resources)
 
     ### choose reflector backend
@@ -119,7 +121,12 @@
 
     ### sync with hosts
     os.chdir(conf['main']['basedir'])
-    for resource in resources:
+    for index, resource in enumerate(resources):
+
+        # echo resource
+        log("syncing:'%s' [%d/%d]" % (resource, index, len(resources)))
+
+        # loop over hosts
         for host in hosts:
             reflector.sync(host, resource, resources[resource]['ignore'], pw.get('host'), test)
     os.chdir(cwd)
@@ -151,13 +158,11 @@
         else:
             conf = make_config(user_conf)
 
-    # XXX needed for now
-    assert conf['main']['basedir'] == home()
-
     # fix up configuration from command line options
     conf['hosts'] = set(options.hosts or conf['main']['hosts'])
     conf['main']['password'] = options.password and conf['main']['password']
 
+    # mirror all the things
     unify(conf, args, options.test)
 
 if __name__ == '__main__':