"""Read imported metadata even when Grocy's sanitizer removes the pre tag.""" import json from html import escape from lxml import html def read_metadata(description): try: text = html.fromstring(description or '

').text_content() except (html.etree.ParserError, ValueError): return {} for index, character in enumerate(text): if character == '{': try: value, _ = json.JSONDecoder().raw_decode(text[index:]) if isinstance(value, dict) and 'Ocado product ID' in value: return value except ValueError: pass return {} def replace_metadata(description, metadata): tree = html.fragment_fromstring(description, create_parent='div') for node in tree.iter(): for attr in ('text', 'tail'): text = getattr(node, attr) or '' for index, character in enumerate(text): if character != '{': continue try: old, end = json.JSONDecoder().raw_decode(text[index:]) except ValueError: continue if isinstance(old, dict) and 'Ocado product ID' in old: setattr(node, attr, text[:index] + json.dumps(metadata, ensure_ascii=False, indent=2) + text[index + end:]) return escape(tree.text or '') + ''.join(html.tostring(child, encoding='unicode') for child in tree) raise ValueError('Cannot safely locate imported metadata in description')