mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-03-25 08:55:50 +00:00
Actually make start_date and end_date work
Some CLI improvements
This commit is contained in:
parent
54adf78f05
commit
993ddc9737
5 changed files with 40 additions and 14 deletions
|
|
@ -103,18 +103,24 @@ def _main(env, file_cfg):
|
|||
general, all_pairs, all_storages = file_cfg
|
||||
app = argvard.Argvard()
|
||||
|
||||
|
||||
@app.main()
|
||||
def app_main(context):
|
||||
print("Hello.")
|
||||
sys.exit(1)
|
||||
|
||||
@app.option('--debug|-v')
|
||||
def debug_option(context):
|
||||
@app.option('--verbose|-v')
|
||||
def verbose_option(context):
|
||||
'''Print generally more information.'''
|
||||
log.get('cli').setLevel(log.logging.DEBUG)
|
||||
log.get('sync').setLevel(log.logging.DEBUG)
|
||||
sync_verbose_option(context)
|
||||
|
||||
sync_command = argvard.Command()
|
||||
|
||||
@sync_command.option('--verbose|-v')
|
||||
def sync_verbose_option(context):
|
||||
'''Print more information about the syncing process.'''
|
||||
log.get('sync').setLevel(log.logging.DEBUG)
|
||||
|
||||
@sync_command.main('[pairs...]')
|
||||
def sync_main(context, pairs=None):
|
||||
if pairs is None:
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ class Storage(object):
|
|||
- ETAG: Checksum of item, or something similar that changes when the object does
|
||||
'''
|
||||
fileext = '.txt'
|
||||
_repr_attributes = set()
|
||||
|
||||
def __init__(self, item_class=Item):
|
||||
self.item_class = item_class
|
||||
|
|
@ -41,6 +42,12 @@ class Storage(object):
|
|||
def _get_href(self, uid):
|
||||
return uid + self.fileext
|
||||
|
||||
def __repr__(self):
|
||||
return '<{}(**{})>'.format(
|
||||
self.__class__.__name__,
|
||||
dict((x, getattr(self, x)) for x in self._repr_attributes)
|
||||
)
|
||||
|
||||
def list(self):
|
||||
'''
|
||||
:returns: list of (href, etag)
|
||||
|
|
|
|||
|
|
@ -17,13 +17,17 @@ import urlparse
|
|||
import datetime
|
||||
|
||||
CALDAV_DT_FORMAT = '%Y%m%dT%H%M%SZ'
|
||||
CONFIG_DT_FORMAT = '%Y-%m-%d'
|
||||
|
||||
|
||||
class CaldavStorage(Storage):
|
||||
|
||||
'''hrefs are full URLs to items'''
|
||||
_session = None
|
||||
_repr_attributes = ('url', 'username')
|
||||
fileext = '.ics'
|
||||
start_date = None
|
||||
end_date = None
|
||||
|
||||
def __init__(self, url, username='', password='', start_date=None,
|
||||
end_date=None, verify=True, auth='basic',
|
||||
|
|
@ -52,11 +56,18 @@ class CaldavStorage(Storage):
|
|||
else:
|
||||
raise ValueError('Unknown authentication method: {}'.format(auth))
|
||||
|
||||
self.username, self.password = username, password
|
||||
self.useragent = useragent
|
||||
self.url = url.rstrip('/') + '/'
|
||||
self.parsed_url = urlparse.urlparse(self.url)
|
||||
self.start_date = start_date
|
||||
self.end_date = end_date
|
||||
if (start_date is None) != (end_date is None):
|
||||
raise ValueError('If start_date is given, '
|
||||
'end_date has to be given too.')
|
||||
elif start_date is not None and end_date is not None:
|
||||
namespace = dict(datetime.__dict__)
|
||||
namespace['start_date'] = self.start_date = \
|
||||
eval(start_date, namespace)
|
||||
self.end_date = eval(end_date, namespace)
|
||||
|
||||
headers = self._default_headers()
|
||||
headers['Depth'] = 1
|
||||
|
|
@ -109,13 +120,13 @@ class CaldavStorage(Storage):
|
|||
</C:calendar-query>'''
|
||||
start = self.start_date
|
||||
end = self.end_date
|
||||
if start or end:
|
||||
start = start or datetime.datetime.utcnow()
|
||||
end = end or start + datetime.timedelta(days=365)
|
||||
if start and end:
|
||||
start = start.strftime(CALDAV_DT_FORMAT)
|
||||
end = end.strftime(CALDAV_DT_FORMAT)
|
||||
caldavfilter = ('<C:comp-filter name="VTODO">'
|
||||
'<C:time-range start="{start}" end="{end}"/>'
|
||||
'</C:comp-filter>').format(start=start.strftime(CALDAV_DT_FORMAT),
|
||||
end=end.strftime(CALDAV_DT_FORMAT))
|
||||
'</C:comp-filter>').format(start=start,
|
||||
end=end)
|
||||
data = data.format(caldavfilter=caldavfilter)
|
||||
else:
|
||||
data = data.format(caldavfilter='')
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ class FilesystemStorage(Storage):
|
|||
mtime is etag
|
||||
filename without path is href'''
|
||||
|
||||
_repr_attributes = ('path',)
|
||||
|
||||
def __init__(self, path, fileext, encoding='utf-8', **kwargs):
|
||||
'''
|
||||
:param path: Absolute path to a *collection* inside a vdir.
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ def sync(storage_a, storage_b, status):
|
|||
# href => {'etag': etag, 'obj': optional object, 'uid': uid}
|
||||
list_a = dict(prepare_list(storage_a, a_href_to_uid))
|
||||
list_b = dict(prepare_list(storage_b, b_href_to_uid))
|
||||
|
||||
a_uid_to_href = dict((x['uid'], href) for href, x in list_a.iteritems())
|
||||
b_uid_to_href = dict((x['uid'], href) for href, x in list_b.iteritems())
|
||||
del a_href_to_uid, b_href_to_uid
|
||||
|
|
@ -80,9 +81,9 @@ def sync(storage_a, storage_b, status):
|
|||
}
|
||||
|
||||
for action, uid, source, dest in actions:
|
||||
sync_logger.debug((action, uid, source, dest))
|
||||
source_storage, source_list, source_uid_to_href = storages[source]
|
||||
dest_storage, dest_list, dest_uid_to_href = storages[dest]
|
||||
sync_logger.debug((action, uid, source_storage, dest_storage))
|
||||
|
||||
if action in ('upload', 'update'):
|
||||
source_href = source_uid_to_href[uid]
|
||||
|
|
@ -121,11 +122,10 @@ def get_actions(list_a, list_b, status, a_uid_to_href, b_uid_to_href):
|
|||
b = list_b.get(href_b, None)
|
||||
if uid not in status:
|
||||
if uid in uids_a and uid in uids_b: # missing status
|
||||
# TODO: might need some kind of diffing too?
|
||||
assert type(a['obj'].raw) is unicode, repr(a['obj'].raw)
|
||||
assert type(b['obj'].raw) is unicode, repr(b['obj'].raw)
|
||||
if a['obj'].raw != b['obj'].raw:
|
||||
raise NotImplementedError(
|
||||
raise NotImplementedError( # TODO
|
||||
'Conflict. No status and '
|
||||
'different content on both sides.'
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue