mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-27 14:57:41 +00:00
Move functionality to cli utils
This commit is contained in:
parent
c8c7305cbf
commit
a5cb7b197b
2 changed files with 43 additions and 43 deletions
|
|
@ -2,14 +2,12 @@
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
import json
|
import json
|
||||||
import uuid
|
|
||||||
|
|
||||||
from .utils import CliError, JobFailed, cli_logger, collections_for_pair, \
|
from .utils import CliError, JobFailed, cli_logger, collections_for_pair, \
|
||||||
get_status_name, handle_cli_error, load_status, save_status, \
|
get_status_name, handle_cli_error, load_status, repair_storage, \
|
||||||
storage_class_from_config, storage_instance_from_config
|
save_status, storage_class_from_config, storage_instance_from_config
|
||||||
|
|
||||||
from ..sync import sync
|
from ..sync import sync
|
||||||
from ..utils.vobject import Item
|
|
||||||
|
|
||||||
|
|
||||||
def sync_pair(wq, pair_name, collections_to_sync, general, all_pairs,
|
def sync_pair(wq, pair_name, collections_to_sync, general, all_pairs,
|
||||||
|
|
@ -111,42 +109,4 @@ def repair_collection(general, all_pairs, all_storages, collection):
|
||||||
|
|
||||||
cli_logger.info('Repairing {}/{}'.format(storage_name, collection))
|
cli_logger.info('Repairing {}/{}'.format(storage_name, collection))
|
||||||
cli_logger.warning('Make sure no other program is talking to the server.')
|
cli_logger.warning('Make sure no other program is talking to the server.')
|
||||||
_repair_collection(storage)
|
repair_storage(storage)
|
||||||
|
|
||||||
|
|
||||||
def _repair_collection(storage):
|
|
||||||
seen_uids = set()
|
|
||||||
all_hrefs = list(storage.list())
|
|
||||||
for i, (href, _) in enumerate(all_hrefs):
|
|
||||||
item, etag = storage.get(href)
|
|
||||||
cli_logger.info('[{}/{}] Processing {}'
|
|
||||||
.format(i, len(all_hrefs), href))
|
|
||||||
|
|
||||||
parsed = item.parsed
|
|
||||||
changed = False
|
|
||||||
if parsed is None:
|
|
||||||
cli_logger.warning('Item {} can\'t be parsed, skipping.'
|
|
||||||
.format(href))
|
|
||||||
continue
|
|
||||||
|
|
||||||
if item.uid is None or item.uid in seen_uids:
|
|
||||||
if item.uid is None:
|
|
||||||
cli_logger.warning('No UID, assigning random one.')
|
|
||||||
else:
|
|
||||||
cli_logger.warning('Duplicate UID, reassigning random one.')
|
|
||||||
|
|
||||||
new_uid = uuid.uuid4()
|
|
||||||
stack = [parsed]
|
|
||||||
while stack:
|
|
||||||
component = stack.pop()
|
|
||||||
if component.name in ('VEVENT', 'VTODO', 'VJOURNAL', 'VCARD'):
|
|
||||||
component['UID'] = new_uid
|
|
||||||
changed = True
|
|
||||||
else:
|
|
||||||
stack.extend(component.subcomponents)
|
|
||||||
|
|
||||||
new_item = Item(u'\r\n'.join(parsed.dump_lines()))
|
|
||||||
assert new_item.uid
|
|
||||||
seen_uids.add(new_item.uid)
|
|
||||||
if changed:
|
|
||||||
storage.update(href, new_item, etag)
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import os
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
|
import uuid
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
from atomicwrites import atomic_write
|
from atomicwrites import atomic_write
|
||||||
|
|
@ -17,6 +18,7 @@ from ..storage import storage_names
|
||||||
from ..sync import IdentConflict, StorageEmpty, SyncConflict
|
from ..sync import IdentConflict, StorageEmpty, SyncConflict
|
||||||
from ..utils import expand_path, get_class_init_args
|
from ..utils import expand_path, get_class_init_args
|
||||||
from ..utils.compat import text_type
|
from ..utils.compat import text_type
|
||||||
|
from ..utils.vobject import Item
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -604,3 +606,41 @@ def format_storage_config(cls, header=True):
|
||||||
comment = '' if key not in defaults else '#'
|
comment = '' if key not in defaults else '#'
|
||||||
value = defaults.get(key, '...')
|
value = defaults.get(key, '...')
|
||||||
yield '{}{} = {}'.format(comment, key, json.dumps(value))
|
yield '{}{} = {}'.format(comment, key, json.dumps(value))
|
||||||
|
|
||||||
|
|
||||||
|
def repair_storage(storage):
|
||||||
|
seen_uids = set()
|
||||||
|
all_hrefs = list(storage.list())
|
||||||
|
for i, (href, _) in enumerate(all_hrefs):
|
||||||
|
item, etag = storage.get(href)
|
||||||
|
cli_logger.info('[{}/{}] Processing {}'
|
||||||
|
.format(i, len(all_hrefs), href))
|
||||||
|
|
||||||
|
parsed = item.parsed
|
||||||
|
changed = False
|
||||||
|
if parsed is None:
|
||||||
|
cli_logger.warning('Item {} can\'t be parsed, skipping.'
|
||||||
|
.format(href))
|
||||||
|
continue
|
||||||
|
|
||||||
|
if item.uid is None or item.uid in seen_uids:
|
||||||
|
if item.uid is None:
|
||||||
|
cli_logger.warning('No UID, assigning random one.')
|
||||||
|
else:
|
||||||
|
cli_logger.warning('Duplicate UID, reassigning random one.')
|
||||||
|
|
||||||
|
new_uid = uuid.uuid4()
|
||||||
|
stack = [parsed]
|
||||||
|
while stack:
|
||||||
|
component = stack.pop()
|
||||||
|
if component.name in ('VEVENT', 'VTODO', 'VJOURNAL', 'VCARD'):
|
||||||
|
component['UID'] = new_uid
|
||||||
|
changed = True
|
||||||
|
else:
|
||||||
|
stack.extend(component.subcomponents)
|
||||||
|
|
||||||
|
new_item = Item(u'\r\n'.join(parsed.dump_lines()))
|
||||||
|
assert new_item.uid
|
||||||
|
seen_uids.add(new_item.uid)
|
||||||
|
if changed:
|
||||||
|
storage.update(href, new_item, etag)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue