mirror of
https://gitlab.com/wgp/dougal/software.git
synced 2025-12-06 09:37:08 +00:00
Add functions for translating paths.
The Dougal database will no longer store physical file paths but rather logical ones, relative to (config.yaml).imports.paths. These functions translate between physical and logical paths.
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import pathlib
|
||||||
from glob import glob
|
from glob import glob
|
||||||
from yaml import full_load as _load
|
from yaml import full_load as _load
|
||||||
|
|
||||||
@@ -87,3 +88,73 @@ def rxflags (flagstr):
|
|||||||
for flag in flagstr:
|
for flag in flagstr:
|
||||||
flags |= cases.get(flag, 0)
|
flags |= cases.get(flag, 0)
|
||||||
return flags
|
return flags
|
||||||
|
|
||||||
|
def translate_path (file):
|
||||||
|
"""
|
||||||
|
Translate a path from a Dougal import directory to an actual
|
||||||
|
physical path on disk.
|
||||||
|
|
||||||
|
Any user files accessible by Dougal must be under a path prefixed
|
||||||
|
by `(config.yaml).imports.paths`. The value of `imports.paths` may
|
||||||
|
be either a string, in which case this represents the prefix under
|
||||||
|
which all Dougal data resides, or a dictionary where the keys are
|
||||||
|
logical paths and their values the corresponding physical path.
|
||||||
|
"""
|
||||||
|
cfg = read()
|
||||||
|
root = pathlib.Path(DOUGAL_ROOT)
|
||||||
|
filepath = pathlib.Path(file).resolve()
|
||||||
|
import_paths = cfg["imports"]["paths"]
|
||||||
|
|
||||||
|
if filepath.is_absolute():
|
||||||
|
if type(import_paths) == str:
|
||||||
|
# Substitute the root for the real physical path
|
||||||
|
# NOTE: `root` deals with import_paths not being absolute
|
||||||
|
prefix = root.joinpath(pathlib.Path(import_paths)).resolve()
|
||||||
|
return str(pathlib.Path(prefix).joinpath(*filepath.parts[2:]))
|
||||||
|
else:
|
||||||
|
# Look for a match on the second path element
|
||||||
|
if filepath.parts[1] in import_paths:
|
||||||
|
# NOTE: `root` deals with import_paths[…] not being absolute
|
||||||
|
prefix = root.joinpath(import_paths[filepath.parts[1]])
|
||||||
|
return str(pathlib.Path(prefix).joinpath(*filepath.parts[2:]))
|
||||||
|
else:
|
||||||
|
# This path is invalid
|
||||||
|
raise TypeError("invalid path or file: {0!r}".format(filepath))
|
||||||
|
else:
|
||||||
|
# A relative filepath is always resolved relative to the logical root
|
||||||
|
root = pathlib.Path("/")
|
||||||
|
return translate_path(root.joinpath(filepath))
|
||||||
|
|
||||||
|
def untranslate_path (file):
|
||||||
|
"""
|
||||||
|
Attempt to convert a physical path into a logical one.
|
||||||
|
See `translate_path()` above for details.
|
||||||
|
"""
|
||||||
|
cfg = read()
|
||||||
|
dougal_root = pathlib.Path(DOUGAL_ROOT)
|
||||||
|
filepath = pathlib.Path(file).resolve()
|
||||||
|
import_paths = cfg["imports"]["paths"]
|
||||||
|
physical_root = pathlib.Path("/")
|
||||||
|
|
||||||
|
if filepath.is_absolute():
|
||||||
|
if type(import_paths) == str:
|
||||||
|
if filepath.is_relative_to(import_paths):
|
||||||
|
physical_root = pathlib.Path("/")
|
||||||
|
physical_prefix = pathlib.Path(import_paths)
|
||||||
|
return str(root.joinpath(filepath.relative_to(physical_prefix)))
|
||||||
|
else:
|
||||||
|
raise TypeError("invalid path or file: {0!r}".format(filepath))
|
||||||
|
else:
|
||||||
|
for key, value in import_paths.items():
|
||||||
|
value = dougal_root.joinpath(value)
|
||||||
|
physical_prefix = pathlib.Path(value)
|
||||||
|
if filepath.is_relative_to(physical_prefix):
|
||||||
|
logical_prefix = physical_root.joinpath(pathlib.Path(key)).resolve()
|
||||||
|
return str(logical_prefix.joinpath(filepath.relative_to(physical_prefix)))
|
||||||
|
|
||||||
|
# If we got here with no matches, this is not a valid
|
||||||
|
# Dougal data path
|
||||||
|
raise TypeError("invalid path or file: {0!r}".format(filepath))
|
||||||
|
else:
|
||||||
|
# A relative filepath is always resolved relative to DOUGAL_ROOT
|
||||||
|
return untranslate_path(root.joinpath(filepath))
|
||||||
|
|||||||
Reference in New Issue
Block a user