Proxy for a pack URI (partname). Provides utility properties the baseURI and the filename slice. Behaves as |str| otherwise.
| 7 | |
| 8 | |
| 9 | class PackURI(str): |
| 10 | """Proxy for a pack URI (partname). |
| 11 | |
| 12 | Provides utility properties the baseURI and the filename slice. Behaves as |str| otherwise. |
| 13 | """ |
| 14 | |
| 15 | _filename_re = re.compile("([a-zA-Z]+)([0-9][0-9]*)?") |
| 16 | |
| 17 | def __new__(cls, pack_uri_str: str): |
| 18 | if not pack_uri_str[0] == "/": |
| 19 | raise ValueError(f"PackURI must begin with slash, got {repr(pack_uri_str)}") |
| 20 | return str.__new__(cls, pack_uri_str) |
| 21 | |
| 22 | @staticmethod |
| 23 | def from_rel_ref(baseURI: str, relative_ref: str) -> PackURI: |
| 24 | """Construct an absolute pack URI formed by translating `relative_ref` onto `baseURI`.""" |
| 25 | joined_uri = posixpath.join(baseURI, relative_ref) |
| 26 | abs_uri = posixpath.abspath(joined_uri) |
| 27 | return PackURI(abs_uri) |
| 28 | |
| 29 | @property |
| 30 | def baseURI(self) -> str: |
| 31 | """The base URI of this pack URI; the directory portion, roughly speaking. |
| 32 | |
| 33 | E.g. `"/ppt/slides"` for `"/ppt/slides/slide1.xml"`. |
| 34 | |
| 35 | For the package pseudo-partname "/", the baseURI is "/". |
| 36 | """ |
| 37 | return posixpath.split(self)[0] |
| 38 | |
| 39 | @property |
| 40 | def ext(self) -> str: |
| 41 | """The extension portion of this pack URI. |
| 42 | |
| 43 | E.g. `"xml"` for `"/ppt/slides/slide1.xml"`. Note the leading period is not included. |
| 44 | """ |
| 45 | # -- raw_ext is either empty string or starts with period, e.g. ".xml" -- |
| 46 | raw_ext = posixpath.splitext(self)[1] |
| 47 | return raw_ext[1:] if raw_ext.startswith(".") else raw_ext |
| 48 | |
| 49 | @property |
| 50 | def filename(self) -> str: |
| 51 | """The "filename" portion of this pack URI. |
| 52 | |
| 53 | E.g. `"slide1.xml"` for `"/ppt/slides/slide1.xml"`. |
| 54 | |
| 55 | For the package pseudo-partname "/", `filename` is ''. |
| 56 | """ |
| 57 | return posixpath.split(self)[1] |
| 58 | |
| 59 | @property |
| 60 | def idx(self) -> int | None: |
| 61 | """Optional int partname index. |
| 62 | |
| 63 | Value is an integer for an "array" partname or None for singleton partname, e.g. `21` for |
| 64 | `"/ppt/slides/slide21.xml"` and |None| for `"/ppt/presentation.xml"`. |
| 65 | """ |
| 66 | filename = self.filename |
no outgoing calls
searching dependent graphs…