Skip to content

Commit

Permalink
Automatically create missing collections
Browse files Browse the repository at this point in the history
  • Loading branch information
untitaker committed Dec 14, 2014
1 parent 695d690 commit cb121b6
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 17 deletions.
13 changes: 8 additions & 5 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,18 +278,19 @@ def test_collections_cache_invalidation(tmpdir):
[pair foobar]
a = foo
b = bar
collections = a, b, c
''').format(str(tmpdir)))

foo = tmpdir.mkdir('foo')
tmpdir.mkdir('bar')
foo.join('itemone.txt').write('UID:itemone')
bar = tmpdir.mkdir('bar')
foo.mkdir('a').join('itemone.txt').write('UID:itemone')

runner = CliRunner()
result = runner.invoke(cli.app, ['sync'],
env={'VDIRSYNCER_CONFIG': str(cfg)})
assert not result.exception

rv = tmpdir.join('bar').listdir()
rv = bar.join('a').listdir()
assert len(rv) == 1
assert rv[0].basename == 'itemone.txt'

Expand All @@ -310,14 +311,16 @@ def test_collections_cache_invalidation(tmpdir):
[pair foobar]
a = foo
b = bar
collections = a, b, c
''').format(str(tmpdir)))

tmpdir.join('status').remove()
bar2 = tmpdir.mkdir('bar2')
result = runner.invoke(cli.app, ['sync'],
env={'VDIRSYNCER_CONFIG': str(cfg)})
assert not result.exception

rv = tmpdir.join('bar').listdir()
rv2 = tmpdir.join('bar2').listdir()
rv = bar.join('a').listdir()
rv2 = tmpdir.join('bar2').join('a').listdir()
assert len(rv) == len(rv2) == 1
assert rv[0].basename == rv2[0].basename == 'itemone.txt'
32 changes: 20 additions & 12 deletions vdirsyncer/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,20 +191,28 @@ def _discover_from_config(config):
rv[args['collection']] = args
return rv

def _get_coll(discovered, collection, storage_name):
def _get_coll(discovered, collection, storage_name, config):
try:
return discovered[collection]
except KeyError:
raise CliError(
'Unable to find collection {collection!r} for storage '
'{storage_name!r}.\n For pair {pair_name!r}, you wanted to '
'use the collections {shortcut!r}, which yielded '
'{collection!r} (amongst others). Vdirsyncer was unable to '
'find an equivalent collection for the other storage.'.format(
collection=collection, shortcut=shortcut,
storage_name=storage_name, pair_name=pair_name
storage_type = config['type']
cls, config = storage_class_from_config(config)
try:
rv = cls.join_collection(collection=collection, **config)
rv['type'] = storage_type
return rv
except NotImplementedError:
raise CliError(
'Unable to find collection {collection!r} for storage '
'{storage_name!r}.\n For pair {pair_name!r}, you wanted '
'to use the collections {shortcut!r}, which yielded '
'{collection!r} (amongst others). Vdirsyncer was unable '
'to find an equivalent collection for the other '
'storage.'.format(
collection=collection, shortcut=shortcut,
storage_name=storage_name, pair_name=pair_name
)
)
)

shortcuts = set(_parse_old_config_list_value(pair_options, 'collections'))
if not shortcuts:
Expand All @@ -221,8 +229,8 @@ def _get_coll(discovered, collection, storage_name):
collections = [shortcut]

for collection in collections:
a_args = _get_coll(a_discovered, collection, name_a)
b_args = _get_coll(b_discovered, collection, name_b)
a_args = _get_coll(a_discovered, collection, name_a, config_a)
b_args = _get_coll(b_discovered, collection, name_b, config_b)
yield collection, a_args, b_args


Expand Down
7 changes: 7 additions & 0 deletions vdirsyncer/storage/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ class to obtain a storage instance pointing to this collection. It
'''
raise NotImplementedError()

@classmethod
def join_collection(cls, collection, **kwargs):
'''Append the collection to the URL or path specified in ``**kwargs``
and return the new arguments.
'''
raise NotImplementedError()

def __repr__(self):
return self.instance_name or '<{}(**{})>'.format(
self.__class__.__name__,
Expand Down
5 changes: 5 additions & 0 deletions vdirsyncer/storage/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ def discover(cls, path, **kwargs):
**kwargs)
yield args

@classmethod
def join_collection(cls, collection, **kwargs):
kwargs['path'] = os.path.join(kwargs['path'], collection)
return kwargs

def _get_filepath(self, href):
return os.path.join(self.path, href)

Expand Down

0 comments on commit cb121b6

Please sign in to comment.