Fix metadata overwrite issue
authorJakob <jakob@jcornell.net>
Sat, 23 Nov 2019 07:04:51 +0000 (01:04 -0600)
committerJakob <jakob@jcornell.net>
Sat, 23 Nov 2019 07:04:51 +0000 (01:04 -0600)
fs.py
main.py

diff --git a/fs.py b/fs.py
index ea8d04bcf37026c23fce262e8736a895f23e76fd..d641ef374ad5930b69b38d21b17abead3b15ab50 100644 (file)
--- 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 06ce2acd0128436922195bdcf155d4be541632a8..bfe182030e204a5212c6e0718f5e4de7ac35dab2 100644 (file)
--- 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)