diff --git a/docs/info/release-history.rst b/docs/info/release-history.rst index b8a5b61..b21aa42 100644 --- a/docs/info/release-history.rst +++ b/docs/info/release-history.rst @@ -31,6 +31,17 @@ Release History The format is based on `Keep a Changelog `_, and this project adheres to `Semantic Versioning `_ + +1.1.5 +===== + +Fixed +----- +* Bug in escaping of '&' characters when export :py:class:`.XAutoPF` playlists with the :py:class:`.XMLPlaylistParser`. + Was previously escaping multiple times when already escaped e.g. '&' > '&'. + Now correctly skips already occurrences of '&'. + + 1.1.4 ===== diff --git a/musify/libraries/local/playlist/xautopf.py b/musify/libraries/local/playlist/xautopf.py index b4c3c9a..4999824 100644 --- a/musify/libraries/local/playlist/xautopf.py +++ b/musify/libraries/local/playlist/xautopf.py @@ -1,6 +1,7 @@ """ The XAutoPF implementation of a :py:class:`LocalPlaylist`. """ +import re from collections.abc import Collection, Mapping, Sequence from copy import deepcopy from dataclasses import dataclass @@ -513,12 +514,13 @@ def parse_exception_paths( include_items = tuple(items_mapped[path] for path in matcher.include if path in items_mapped) exclude_items = tuple(matched_mapped[path] for path in matcher.exclude if path in matched_mapped) + amp_pattern = re.compile('&(?!amp;)') if len(include_items) > 0: include_paths = self.path_mapper.unmap_many(include_items, check_existence=False) - self.xml_source["ExceptionsInclude"] = "|".join(include_paths).replace("&", "&") + self.xml_source["ExceptionsInclude"] = amp_pattern.sub("&", "|".join(include_paths)) if len(exclude_items) > 0: exclude_paths = self.path_mapper.unmap_many(exclude_items, check_existence=False) - self.xml_source["Exceptions"] = "|".join(exclude_paths).replace("&", "&") + self.xml_source["Exceptions"] = amp_pattern.sub("&", "|".join(exclude_paths)) def get_limiter(self) -> ItemLimiter | None: """Initialise and return a :py:class:`ItemLimiter` object from loaded XML playlist data."""