mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-27 14:57:41 +00:00
CLI WIP
This commit is contained in:
parent
f94649950e
commit
dc12b74805
5 changed files with 109 additions and 21 deletions
2
setup.py
2
setup.py
|
|
@ -25,5 +25,5 @@ setup(
|
||||||
entry_points={
|
entry_points={
|
||||||
'console_scripts': ['vdirsyncer = vdirsyncer.cli:main']
|
'console_scripts': ['vdirsyncer = vdirsyncer.cli:main']
|
||||||
},
|
},
|
||||||
install_requires=['argvard']
|
install_requires=['argvard', 'requests']
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -8,21 +8,69 @@
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
from vdirsyncer.sync import sync_classes
|
from vdirsyncer.sync import sync
|
||||||
|
from vdirsyncer.storage.caldav import CaldavStorage
|
||||||
|
from vdirsyncer.storage.filesystem import FilesystemStorage
|
||||||
|
from vdirsyncer.utils import expand_path
|
||||||
|
import argvard
|
||||||
|
|
||||||
|
|
||||||
def _path(p):
|
storage_names = {
|
||||||
p = os.path.expanduser(p)
|
'caldav': CaldavStorage,
|
||||||
p = os.path.abspath(p)
|
'filesystem': FilesystemStorage
|
||||||
return p
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_config_parser(env):
|
def get_config_parser(env):
|
||||||
fname = env.get('VDIRSYNCER_CONFIG', _path('~/.vdirsyncer/config'))
|
fname = env.get('VDIRSYNCER_CONFIG', expand_path('~/.vdirsyncer/config'))
|
||||||
c = ConfigParser.SafeConfigParser()
|
c = ConfigParser.RawConfigParser()
|
||||||
c.read(fname)
|
c.read(fname)
|
||||||
return dict((c, c.items(c)) for c in c.sections())
|
pairs = {}
|
||||||
|
storages = {}
|
||||||
|
for section in c.sections():
|
||||||
|
if section.startswith('storage '):
|
||||||
|
name = section[len('storage '):]
|
||||||
|
storages.setdefault(name, {}).update(c.items(section))
|
||||||
|
elif section.startswith('pair '):
|
||||||
|
name = section[len('pair '):]
|
||||||
|
options = dict(c.items(section))
|
||||||
|
pairs[name] = a, b = (options.pop('a'), options.pop('b'))
|
||||||
|
storages.setdefault(a, {}).update(options)
|
||||||
|
storages.setdefault(b, {}).update(options)
|
||||||
|
elif section == 'general':
|
||||||
|
general = dict(c.items(section))
|
||||||
|
else:
|
||||||
|
raise RuntimeError('Unknown section: {}'.format(section))
|
||||||
|
|
||||||
|
return general, pairs, storages
|
||||||
|
|
||||||
|
|
||||||
|
def load_status(basepath, pair_name):
|
||||||
|
full_path = os.path.join(expand_path(basepath), pair_name)
|
||||||
|
if not os.path.exists(full_path):
|
||||||
|
return {}
|
||||||
|
with open(full_path) as f:
|
||||||
|
return dict(json.loads(line) for line in f)
|
||||||
|
|
||||||
|
|
||||||
|
def save_status(basepath, pair_name, status):
|
||||||
|
full_path = os.path.join(expand_path(basepath), pair_name)
|
||||||
|
with open(full_path, 'w+') as f:
|
||||||
|
for k, v in status.items():
|
||||||
|
json.dump((k, v), f)
|
||||||
|
|
||||||
|
|
||||||
|
def storage_instance_from_config(config):
|
||||||
|
config = dict(config)
|
||||||
|
cls = storage_names[config.pop('type')]
|
||||||
|
try:
|
||||||
|
return cls(**config)
|
||||||
|
except TypeError:
|
||||||
|
print(config)
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
@ -32,16 +80,40 @@ def main():
|
||||||
|
|
||||||
|
|
||||||
def _main(env, file_cfg):
|
def _main(env, file_cfg):
|
||||||
|
general, all_pairs, all_storages = file_cfg
|
||||||
app = argvard.Argvard()
|
app = argvard.Argvard()
|
||||||
|
|
||||||
sync = argvard.Command()
|
|
||||||
|
|
||||||
@sync_command.main('[accounts...]')
|
@app.main()
|
||||||
def sync_main(accounts=None):
|
def app_main(context):
|
||||||
if accounts is None:
|
print("heY")
|
||||||
accounts = list(file_cfg.keys())
|
|
||||||
for account in accounts:
|
sync_command = argvard.Command()
|
||||||
account_cfg = dict(file_cfg[account])
|
|
||||||
del account_cfg['type']
|
|
||||||
syncer = sync_classes[account_cfg['type']](**account_cfg)
|
@sync_command.main('[pairs...]')
|
||||||
syncer.run()
|
def sync_main(context, pairs=None):
|
||||||
|
if pairs is None:
|
||||||
|
pairs = list(all_pairs)
|
||||||
|
actions = []
|
||||||
|
for pair_name in pairs:
|
||||||
|
try:
|
||||||
|
a, b = all_pairs[pair_name]
|
||||||
|
except KeyError:
|
||||||
|
print('Pair not found: {}'.format(pair_name))
|
||||||
|
print(file_cfg)
|
||||||
|
sys.exit(1)
|
||||||
|
a = storage_instance_from_config(all_storages[a])
|
||||||
|
b = storage_instance_from_config(all_storages[b])
|
||||||
|
|
||||||
|
def x(a=a, b=b, pair_name=pair_name):
|
||||||
|
status = load_status(general['status_path'], pair_name)
|
||||||
|
sync(a, b, status)
|
||||||
|
save_status(general['status_path'], pair_name, status)
|
||||||
|
actions.append(x)
|
||||||
|
|
||||||
|
for action in actions:
|
||||||
|
action()
|
||||||
|
|
||||||
|
app.register_command('sync', sync_command)
|
||||||
|
app()
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ class CaldavStorage(Storage):
|
||||||
if self._session is None:
|
if self._session is None:
|
||||||
self._session = requests.session()
|
self._session = requests.session()
|
||||||
assert '/' not in item
|
assert '/' not in item
|
||||||
path = self.url + item
|
url = self.url + item
|
||||||
return self._session.request(method, url, data=data, headers=headers, **self._settings)
|
return self._session.request(method, url, data=data, headers=headers, **self._settings)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
import os
|
import os
|
||||||
from vdirsyncer.storage.base import Storage, Item
|
from vdirsyncer.storage.base import Storage, Item
|
||||||
import vdirsyncer.exceptions as exceptions
|
import vdirsyncer.exceptions as exceptions
|
||||||
|
from vdirsyncer.utils import expand_path
|
||||||
|
|
||||||
|
|
||||||
class FilesystemStorage(Storage):
|
class FilesystemStorage(Storage):
|
||||||
|
|
@ -22,7 +23,7 @@ class FilesystemStorage(Storage):
|
||||||
'''
|
'''
|
||||||
:param path: Absolute path to a *collection* inside a vdir.
|
:param path: Absolute path to a *collection* inside a vdir.
|
||||||
'''
|
'''
|
||||||
self.path = path
|
self.path = expand_path(path)
|
||||||
self.fileext = fileext
|
self.fileext = fileext
|
||||||
super(FilesystemStorage, self).__init__(**kwargs)
|
super(FilesystemStorage, self).__init__(**kwargs)
|
||||||
|
|
||||||
|
|
|
||||||
15
vdirsyncer/utils.py
Normal file
15
vdirsyncer/utils.py
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
vdirsyncer.utils
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
:copyright: (c) 2014 Markus Unterwaditzer
|
||||||
|
:license: MIT, see LICENSE for more details.
|
||||||
|
'''
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
def expand_path(p):
|
||||||
|
p = os.path.expanduser(p)
|
||||||
|
p = os.path.abspath(p)
|
||||||
|
return p
|
||||||
Loading…
Reference in a new issue