From: Jakob Date: Sat, 23 Nov 2019 07:04:51 +0000 (-0600) Subject: Fix metadata overwrite issue X-Git-Url: https://jcornell.net/gitweb/gitweb.cgi?a=commitdiff_plain;h=81b2bef922f5b50d4f1c7d624efe55319caf239b;p=bb-sync-api.git Fix metadata overwrite issue --- diff --git a/fs.py b/fs.py index ea8d04b..d641ef3 100644 --- a/fs.py +++ b/fs.py @@ -34,7 +34,8 @@ class WinPath(pathlib.WindowsPath): The other tricky thing is that for some reason Windows has relative paths with drive parts, like `C:some/path'. This is what `joinpath' does with `C:', so we need to manually add a separator to ensure the resulting path actually - points to an ADS. + points to an ADS. This makes the path absolute, but that's okay because there + doesn't seem to be any way to get an ADS on a relative path with a drive. """ def get_ads(self, name): full_name = self.name + ':' + name @@ -73,7 +74,7 @@ BB_META_STREAM_NAME = '8f3b98ea-e227-478f-bb58-5c31db476409' VersionInfo = namedtuple('ParseResult', ['bb_id', 'version']) -VersionInfo.with_version = lambda self, v: VersionInfo(self.bb_id, v) +VersionInfo.next = lambda self, v: VersionInfo(self.bb_id, self.version + 1) def _extract_version(path): @@ -90,7 +91,7 @@ def _extract_version(path): except json.decoder.JSONDecodeError: pass else: - bb_id = metadata.get('bbId') + bb_id = metadata.get('contentId') version = metadata.get('version') version_typecheck = lambda v: isinstance(v, int) if path.is_file() else v is None if isinstance(bb_id, str) and version_typecheck(version): @@ -111,15 +112,15 @@ def get_child_versions(path): from collections import defaultdict results = defaultdict(set) - for path in path.iterdir(): - info = _extract_version(path) + for child in path.iterdir(): + info = _extract_version(child) if info: - results[info].add(path) + results[info].add(child) return results # https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file -def sanitize(seg): +def _sanitize(seg): bad = {*map(chr, range(0, 31 + 1)), *r'<>:"/\|?*'} return seg.translate({ch: '!' for ch in bad}) @@ -132,42 +133,34 @@ def join_content_path(path, content_doc): [child_path] = ver_map[info] return child_path else: - return set_up_new_dir( - path, - content_doc['title'], + new_path = get_new_path(path, content_doc['title']) + write_metadata( + new_path, VersionInfo(bb_id = content_doc['id'], version = None), ) + return new_path -def set_up_new_file(*args): - return _set_up_new_path( - *args, - creator = lambda path: path.open('x').close() - ) - -def set_up_new_dir(*args): - return _set_up_new_path(*args, creator = pathlib.Path.mkdir) - -def _set_up_new_path(parent, base_name, version_info, creator): +def get_new_path(parent, base_name): import itertools - sanitized = sanitize(base_name) + sanitized = _sanitize(base_name) (stem, exts) = _split_name(sanitized) def path_for(ordinal): if ordinal is None: seg = sanitized else: seg = '{stem}({ordinal}){exts}'.format(stem=stem, ordinal=ordinal, exts=exts) - assert seg == sanitize(seg) + assert seg == _sanitize(seg) return parent.joinpath(seg) - path = next( + return next( path for path in map(path_for, itertools.chain([None], itertools.count())) if not path.exists() ) - creator(path) + +def write_metadata(path, version_info): with WinPath(path).get_ads(BB_META_STREAM_NAME).open('x') as f: - json.dump({'bbId': version_info.bb_id, 'version': version_info.version}, f) - return path + json.dump({'contentId': version_info.bb_id, 'version': version_info.version}, f) diff --git a/main.py b/main.py index 06ce2ac..bfe1820 100644 --- a/main.py +++ b/main.py @@ -112,11 +112,12 @@ with StorageManager(Path('saved_state')) as storage_mgr: tmp_path.unlink() else: if match is False: - new_version = latest.with_version(latest.version + 1) + new_version = latest.next() LOGGER.info(" Found new revision ({})".format(new_version.version)) else: new_version = fs.VersionInfo(att_id, 0) LOGGER.info(" Storing initial revision") - dest = fs.set_up_new_file(local_path, attachment_doc['fileName'], new_version) + dest = fs.get_new_path(local_path, attachment_doc['fileName']) LOGGER.info(" Destination: {}".format(dest)) tmp_path.replace(dest) + fs.write_metadata(dest, new_version)