mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-03-25 08:55:50 +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={
|
||||
'console_scripts': ['vdirsyncer = vdirsyncer.cli:main']
|
||||
},
|
||||
install_requires=['argvard']
|
||||
install_requires=['argvard', 'requests']
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,21 +8,69 @@
|
|||
'''
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
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):
|
||||
p = os.path.expanduser(p)
|
||||
p = os.path.abspath(p)
|
||||
return p
|
||||
storage_names = {
|
||||
'caldav': CaldavStorage,
|
||||
'filesystem': FilesystemStorage
|
||||
}
|
||||
|
||||
|
||||
def get_config_parser(env):
|
||||
fname = env.get('VDIRSYNCER_CONFIG', _path('~/.vdirsyncer/config'))
|
||||
c = ConfigParser.SafeConfigParser()
|
||||
fname = env.get('VDIRSYNCER_CONFIG', expand_path('~/.vdirsyncer/config'))
|
||||
c = ConfigParser.RawConfigParser()
|
||||
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():
|
||||
|
|
@ -32,16 +80,40 @@ def main():
|
|||
|
||||
|
||||
def _main(env, file_cfg):
|
||||
general, all_pairs, all_storages = file_cfg
|
||||
app = argvard.Argvard()
|
||||
|
||||
sync = argvard.Command()
|
||||
|
||||
@sync_command.main('[accounts...]')
|
||||
def sync_main(accounts=None):
|
||||
if accounts is None:
|
||||
accounts = list(file_cfg.keys())
|
||||
for account in accounts:
|
||||
account_cfg = dict(file_cfg[account])
|
||||
del account_cfg['type']
|
||||
syncer = sync_classes[account_cfg['type']](**account_cfg)
|
||||
syncer.run()
|
||||
@app.main()
|
||||
def app_main(context):
|
||||
print("heY")
|
||||
|
||||
sync_command = argvard.Command()
|
||||
|
||||
|
||||
@sync_command.main('[pairs...]')
|
||||
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:
|
||||
self._session = requests.session()
|
||||
assert '/' not in item
|
||||
path = self.url + item
|
||||
url = self.url + item
|
||||
return self._session.request(method, url, data=data, headers=headers, **self._settings)
|
||||
|
||||
@staticmethod
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
import os
|
||||
from vdirsyncer.storage.base import Storage, Item
|
||||
import vdirsyncer.exceptions as exceptions
|
||||
from vdirsyncer.utils import expand_path
|
||||
|
||||
|
||||
class FilesystemStorage(Storage):
|
||||
|
|
@ -22,7 +23,7 @@ class FilesystemStorage(Storage):
|
|||
'''
|
||||
:param path: Absolute path to a *collection* inside a vdir.
|
||||
'''
|
||||
self.path = path
|
||||
self.path = expand_path(path)
|
||||
self.fileext = fileext
|
||||
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