Changeset - c9b0c7cf50ed
[Not reviewed]
0 6 0
Lance Edgar (lance) - 11 years ago 2013-12-18 23:50:37
lance@edbob.org
Removed reliance on `edbob.db.engines`.
6 files changed with 32 insertions and 30 deletions:
0 comments (0 inline, 0 general)
rattail/commands.py
Show inline comments
 
@@ -26,24 +26,25 @@
 
``rattail.commands`` -- Commands
 
"""
 

	
 
import sys
 
import platform
 

	
 
import edbob
 
from edbob import commands
 
from edbob.commands import Subcommand
 

	
 
from ._version import __version__
 
from .db import model
 
from .console import Progress
 

	
 

	
 
class Command(commands.Command):
 
    """
 
    The primary command for Rattail.
 
    """
 
    
 
    name = 'rattail'
 
    version = __version__
 
    description = "Retail Software Framework"
 
    long_description = """
 
Rattail is a retail software framework.
 
@@ -150,25 +151,24 @@ class Dump(Subcommand):
 

	
 
    def add_parser_args(self, parser):
 
        parser.add_argument(
 
            '--output', '-o', metavar='FILE',
 
            help="Optional path to output file.  If none is specified, "
 
            "data will be written to standard output.")
 
        parser.add_argument(
 
            'model', help="Model whose data will be dumped.")
 

	
 
    def run(self, args):
 
        from .db import get_session_class
 
        from .db.dump import dump_data
 
        from .console import Progress
 

	
 
        if hasattr(model, args.model):
 
            cls = getattr(model, args.model)
 
        else:
 
            sys.stderr.write("Unknown model: {0}\n".format(args.model))
 
            sys.exit(1)
 

	
 
        progress = None
 
        if self.show_progress:
 
            progress = Progress
 

	
 
        if args.output:
 
@@ -293,35 +293,34 @@ class InitializeDatabase(Subcommand):
 
        print("  {0}".format(obfuscate_url_pw(engine.url)))
 

	
 

	
 
class LoadHostDataCommand(Subcommand):
 
    """
 
    Loads data from the Rattail host database, if one is configured.
 
    """
 

	
 
    name = 'load-host-data'
 
    description = "Load data from host database"
 

	
 
    def run(self, args):
 
        from .console import Progress
 
        from rattail.db import load
 
        from .db import get_engines
 
        from .db import load
 

	
 
        edbob.init_modules(['edbob.db'])
 

	
 
        if 'host' not in edbob.engines:
 
            print "Host engine URL not configured."
 
            return
 
        engines = get_engines(edbob.config)
 
        if 'host' not in engines:
 
            sys.stderr.write("Host engine URL not configured.\n")
 
            sys.exit(1)
 

	
 
        proc = load.LoadProcessor()
 
        proc.load_all_data(edbob.engines['host'], Progress)
 
        proc.load_all_data(engines['host'], Progress)
 

	
 

	
 
class MakeConfigCommand(Subcommand):
 
    """
 
    Creates a sample configuration file.
 
    """
 

	
 
    name = 'make-config'
 
    description = "Create a configuration file"
 

	
 
    def add_parser_args(self, parser):
 
        parser.add_argument('path', default='rattail.conf', metavar='PATH',
rattail/db/sync/__init__.py
Show inline comments
 
@@ -30,43 +30,43 @@ import sys
 
import time
 
import logging
 

	
 
if sys.platform == 'win32': # pragma no cover
 
    import win32api
 

	
 
import sqlalchemy.exc
 
from sqlalchemy.orm import sessionmaker, class_mapper
 
from sqlalchemy.exc import OperationalError
 

	
 
import edbob
 

	
 
from rattail.db import model
 
from .. import model
 
from .. import get_engines
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
def get_sync_engines():
 
    edbob.init_modules(['edbob.db'])
 

	
 
    keys = edbob.config.get('rattail.db', 'syncs')
 
    if not keys:
 
        return None
 

	
 
    engines = {}
 
    engines = get_engines(edbob.config)
 
    sync_engines = {}
 
    for key in keys.split(','):
 
        key = key.strip()
 
        engines[key] = edbob.engines[key]
 
    log.debug("get_sync_engines: Found engine keys: %s" % ','.join(engines.keys()))
 
    return engines
 
        sync_engines[key] = engines[key]
 
    log.debug("get_sync_engines: Found engine keys: %s" % ','.join(sync_engines.keys()))
 
    return sync_engines
 

	
 

	
 
class Synchronizer(object):
 
    """
 
    Default implementation of database synchronization logic.  Subclass this if
 
    you have special processing needs.
 
    """
 

	
 
    # This defines the `model` module which will be used to obtain references
 
    # to model classes (`Product` etc.).  If you need to synchronize custom
 
    # model classes of which Rattail is not aware, you must override this.
 
    # Note that the module you specify must be a superset of Rattail.
rattail/db/sync/linux.py
Show inline comments
 
@@ -18,36 +18,37 @@
 
#  more details.
 
#
 
#  You should have received a copy of the GNU Affero General Public License
 
#  along with Rattail.  If not, see <http://www.gnu.org/licenses/>.
 
#
 
################################################################################
 

	
 
"""
 
``rattail.db.sync.linux`` -- Database Synchronization for Linux
 
"""
 

	
 
import edbob
 
from edbob import db
 

	
 
from ...daemon import Daemon
 
from .. import get_default_engine
 
from . import get_sync_engines, synchronize_changes
 

	
 

	
 
class SyncDaemon(Daemon):
 

	
 
    def run(self):
 
        remote_engines = get_sync_engines()
 
        if remote_engines:
 
            synchronize_changes(db.engine, remote_engines)
 
            local_engine = get_default_engine(edbob.config)
 
            synchronize_changes(local_engine, remote_engines)
 

	
 

	
 
def get_daemon(pidfile=None):
 
    """
 
    Get a :class:`SyncDaemon` instance.
 
    """
 

	
 
    if pidfile is None:
 
        pidfile = edbob.config.get('rattail.db', 'sync.pid_path',
 
                                   default='/var/run/rattail/dbsync.pid')
 
    return SyncDaemon(pidfile)
 

	
rattail/db/sync/win32.py
Show inline comments
 
@@ -22,28 +22,28 @@
 
#
 
################################################################################
 

	
 
"""
 
``rattail.db.sync.win32`` -- Database Synchronization for Windows
 
"""
 

	
 
import sys
 
import logging
 
import threading
 

	
 
import edbob
 
from edbob import db
 

	
 
from rattail.win32.service import Service
 
from rattail.db.sync import get_sync_engines, synchronize_changes
 
from ...win32.service import Service
 
from .. import get_default_engine
 
from . import get_sync_engines, synchronize_changes
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class DatabaseSynchronizerService(Service):
 
    """
 
    Implements database synchronization as a Windows service.
 
    """
 

	
 
    _svc_name_ = 'RattailDatabaseSynchronizer'
 
    _svc_display_name_ = "Rattail : Database Synchronization Service"
 
@@ -52,29 +52,28 @@ class DatabaseSynchronizerService(Service):
 
                         "database(s).")
 

	
 
    appname = 'rattail'
 

	
 
    def Initialize(self):
 
        """
 
        Service initialization.
 
        """
 

	
 
        if not Service.Initialize(self):
 
            return False
 

	
 
        edbob.init_modules(['rattail.db'])
 

	
 
        local_engine = get_default_engine(edbob.config)
 
        remote_engines = get_sync_engines()
 
        if not remote_engines:
 
            return False
 

	
 
        thread = threading.Thread(target=synchronize_changes,
 
                                  args=(db.engine, remote_engines))
 
                                  args=(local_engine, remote_engines))
 
        thread.daemon = True
 
        thread.start()
 
        return True
 

	
 

	
 
if __name__ == '__main__':
 
    if sys.platform == 'win32':
 
        import win32serviceutil
 
        win32serviceutil.HandleCommandLine(DatabaseSynchronizerService)
tests/db/sync/test_init.py
Show inline comments
 
@@ -345,33 +345,33 @@ class SynchronizerTests(SyncTestCase):
 
        session.flush()
 
        assignment = session.query(model.CustomerGroupAssignment).one()
 
        self.assertEqual(assignment.customer_uuid, customer.uuid)
 
        self.assertEqual(assignment.group_uuid, group.uuid)
 
        synchronizer.delete_CustomerGroup(session, group)
 
        self.assertEqual(session.query(model.CustomerGroupAssignment).count(), 0)
 
        session.rollback()
 
        session.close()
 

	
 

	
 
class ModuleTests(TestCase):
 

	
 
    @patch('rattail.db.sync.edbob')
 
    def test_get_sync_engines(self, edbob):
 
    @patch.multiple('rattail.db.sync', edbob=DEFAULT, get_engines=DEFAULT)
 
    def test_get_sync_engines(self, edbob, get_engines):
 

	
 
        # nothing configured
 
        edbob.config.get.return_value = None
 
        self.assertIsNone(sync.get_sync_engines())
 

	
 
        # fake config with 2 out of 3 engines synced
 
        edbob.engines = {
 
        get_engines.return_value = {
 
            'one': 'first',
 
            'two': 'second',
 
            'three': 'third',
 
            }
 
        edbob.config.get.return_value = 'one, two'
 
        engines = sync.get_sync_engines()
 
        self.assertEqual(engines, {'one': 'first', 'two': 'second'})
 

	
 
    @patch.multiple('rattail.db.sync', edbob=DEFAULT, Synchronizer=DEFAULT)
 
    def test_synchronize_changes(self, edbob, Synchronizer):
 

	
 
        local_engine = Mock()
tests/db/sync/test_linux.py
Show inline comments
 

	
 
from unittest import TestCase
 
from mock import patch, DEFAULT
 

	
 
from rattail.db.sync import linux
 

	
 

	
 
class SyncDaemonTests(TestCase):
 

	
 
    @patch.multiple('rattail.db.sync.linux',
 
                    db=DEFAULT,
 
                    edbob=DEFAULT,
 
                    get_default_engine=DEFAULT,
 
                    get_sync_engines=DEFAULT,
 
                    synchronize_changes=DEFAULT)
 
    def test_run(self, db, get_sync_engines, synchronize_changes):
 
    def test_run(self, edbob, get_default_engine, get_sync_engines, synchronize_changes):
 

	
 
        daemon = linux.SyncDaemon('/tmp/rattail_dbsync.pid')
 

	
 
        # no remote engines configured
 
        get_sync_engines.return_value = None
 
        daemon.run()
 
        get_sync_engines.assert_called_once_with()
 
        self.assertFalse(get_default_engine.called)
 
        self.assertFalse(synchronize_changes.called)
 

	
 
        # with remote engines configured
 
        get_sync_engines.return_value = 'fake_remotes'
 
        get_default_engine.return_value = 'fake_local'
 
        daemon.run()
 
        synchronize_changes.assert_called_once_with(db.engine, 'fake_remotes')
 
        synchronize_changes.assert_called_once_with('fake_local', 'fake_remotes')
 

	
 

	
 
class ModuleTests(TestCase):
 

	
 
    @patch.multiple('rattail.db.sync.linux', edbob=DEFAULT, SyncDaemon=DEFAULT)
 
    def test_get_daemon(self, edbob, SyncDaemon):
 

	
 
        # pid file provided
 
        linux.get_daemon('some_pidfile')
 
        self.assertFalse(edbob.config.get.called)
 
        SyncDaemon.assert_called_once_with('some_pidfile')
 

	
0 comments (0 inline, 0 general)