Skip to content

Commit 6d6f1c7

Browse files
author
Xiaozhou Li
authored
Merge pull request #34 from Ultimaker/CS-2323/do-not-replace-non-top-level-dirs
CS-2323 `_aliases`: Do not replace non-top-level directories
2 parents 3ce7b18 + c6c08c8 commit 6d6f1c7

3 files changed

Lines changed: 36 additions & 7 deletions

File tree

Charon/filetypes/GCodeFile.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def parseHeader(stream: IO[bytes], *, prefix: str = "") -> Dict[str, Any]:
9696
@staticmethod
9797
def __insertKeyValuePair(
9898
metadata: Dict[str, Any],
99-
key_elements: Union[str, List[str]],
99+
key_elements: Any,
100100
value: Any
101101
) -> Any:
102102
if not key_elements:
@@ -151,7 +151,7 @@ def __cleanGriffinHeader(metadata: Dict[str, Any]) -> None:
151151
# must exist on the location of that key element
152152
# @return True if the key is available and not empty
153153
@staticmethod
154-
def __isAvailable(metadata: Dict[str, Any], keys: List[str]) -> None:
154+
def __isAvailable(metadata: Dict[str, Any], keys: List[Any]) -> bool:
155155
if not keys:
156156
return True
157157

Charon/filetypes/OpenPackagingConvention.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class OpenPackagingConvention(FileInterface):
2525
_global_metadata_file = "/Metadata/OPC_Global.json" # Where the global metadata file is.
2626
_opc_metadata_relationship_type = "http://schemas.ultimaker.org/package/2018/relationships/opc_metadata" # Unique identifier of the relationship type that relates OPC metadata to files.
2727
_metadata_prefix = "/metadata"
28-
_aliases = OrderedDict([]) # A standard OPC file doest not have default aliases. These must be implemented in inherited classes.
28+
_aliases:Dict[str, str] = OrderedDict([]) # A standard OPC file doest not have default aliases. These must be implemented in inherited classes.
2929

3030
mime_type = "application/x-opc"
3131

@@ -298,7 +298,11 @@ def _processAliases(self, virtual_path: str) -> str:
298298

299299
# Replace all aliases.
300300
for regex, replacement in self._aliases.items():
301-
virtual_path = re.sub(regex, replacement, virtual_path)
301+
if regex.startswith("/"):
302+
expression = rf"^{regex}"
303+
else:
304+
expression = regex
305+
virtual_path = re.sub(expression, replacement, virtual_path)
302306

303307
return virtual_path
304308

tests/filetypes/TestOpenPackagingConvention.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import pytest #This module contains unit tests.
66
import zipfile #To inspect the contents of the zip archives.
77
import xml.etree.ElementTree as ET #To inspect the contents of the OPC-spec files in the archives.
8+
from collections import OrderedDict
9+
from typing import List, Generator
810

911
from Charon.filetypes.OpenPackagingConvention import OpenPackagingConvention, OPCError # The class we're testing.
1012
from Charon.OpenMode import OpenMode #To open archives.
@@ -14,7 +16,7 @@
1416
# The package has no resources at all, so reading from it will not find
1517
# anything.
1618
@pytest.fixture()
17-
def empty_read_opc() -> OpenPackagingConvention:
19+
def empty_read_opc() -> Generator[OpenPackagingConvention, None, None]:
1820
result = OpenPackagingConvention()
1921
result.openStream(open(os.path.join(os.path.dirname(__file__), "resources", "empty.opc"), "rb"))
2022
yield result
@@ -26,7 +28,7 @@ def empty_read_opc() -> OpenPackagingConvention:
2628
# The file is called "hello.txt" and contains the text "Hello world!" encoded
2729
# in UTF-8.
2830
@pytest.fixture()
29-
def single_resource_read_opc() -> OpenPackagingConvention:
31+
def single_resource_read_opc() -> Generator[OpenPackagingConvention, None, None]:
3032
result = OpenPackagingConvention()
3133
result.openStream(open(os.path.join(os.path.dirname(__file__), "resources", "hello.opc"), "rb"))
3234
yield result
@@ -38,7 +40,7 @@ def single_resource_read_opc() -> OpenPackagingConvention:
3840
# Note that you can't really test the output of the write since you don't have
3941
# the stream it writes to.
4042
@pytest.fixture()
41-
def empty_write_opc() -> OpenPackagingConvention:
43+
def empty_write_opc() -> Generator[OpenPackagingConvention, None, None]:
4244
result = OpenPackagingConvention()
4345
result.openStream(io.BytesIO(), "application/x-opc", OpenMode.WriteOnly)
4446
yield result
@@ -89,6 +91,29 @@ def test_cycleSetDataGetData(virtual_path: str):
8991
assert result[virtual_path] == test_data #The data itself is still correct.
9092

9193

94+
@pytest.mark.parametrize("virtual_path, path_list", [
95+
("/foo/materials", ["/foo/materials", "/[Content_Types].xml", "/_rels/.rels"]),
96+
("/materials", ["/files/materials", "/[Content_Types].xml", "/_rels/.rels"])
97+
])
98+
def test_aliases_replacement(virtual_path: str, path_list: List[str]):
99+
test_data = b"Let's see if we can read this data back."
100+
101+
stream = io.BytesIO()
102+
package = OpenPackagingConvention()
103+
package._aliases = OrderedDict([
104+
(r"/materials", "/files/materials")
105+
])
106+
package.openStream(stream, mode = OpenMode.WriteOnly)
107+
package.setData({virtual_path: test_data})
108+
package.close()
109+
110+
stream.seek(0)
111+
package = OpenPackagingConvention()
112+
package.openStream(stream)
113+
result = package.listPaths()
114+
115+
assert result == path_list
116+
92117
## Tests writing data via a stream to an archive, then reading it back via a
93118
# stream.
94119
@pytest.mark.parametrize("virtual_path", ["/dir/file", "/file", "/Metadata"])

0 commit comments

Comments
 (0)