Spaces:
Runtime error
Runtime error
# Extracted from https://github.com/pfmoore/pkg_metadata | |
from email.header import Header, decode_header, make_header | |
from email.message import Message | |
from typing import Any, Dict, List, Union | |
METADATA_FIELDS = [ | |
# Name, Multiple-Use | |
("Metadata-Version", False), | |
("Name", False), | |
("Version", False), | |
("Dynamic", True), | |
("Platform", True), | |
("Supported-Platform", True), | |
("Summary", False), | |
("Description", False), | |
("Description-Content-Type", False), | |
("Keywords", False), | |
("Home-page", False), | |
("Download-URL", False), | |
("Author", False), | |
("Author-email", False), | |
("Maintainer", False), | |
("Maintainer-email", False), | |
("License", False), | |
("Classifier", True), | |
("Requires-Dist", True), | |
("Requires-Python", False), | |
("Requires-External", True), | |
("Project-URL", True), | |
("Provides-Extra", True), | |
("Provides-Dist", True), | |
("Obsoletes-Dist", True), | |
] | |
def json_name(field: str) -> str: | |
return field.lower().replace("-", "_") | |
def msg_to_json(msg: Message) -> Dict[str, Any]: | |
"""Convert a Message object into a JSON-compatible dictionary.""" | |
def sanitise_header(h: Union[Header, str]) -> str: | |
if isinstance(h, Header): | |
chunks = [] | |
for bytes, encoding in decode_header(h): | |
if encoding == "unknown-8bit": | |
try: | |
# See if UTF-8 works | |
bytes.decode("utf-8") | |
encoding = "utf-8" | |
except UnicodeDecodeError: | |
# If not, latin1 at least won't fail | |
encoding = "latin1" | |
chunks.append((bytes, encoding)) | |
return str(make_header(chunks)) | |
return str(h) | |
result = {} | |
for field, multi in METADATA_FIELDS: | |
if field not in msg: | |
continue | |
key = json_name(field) | |
if multi: | |
value: Union[str, List[str]] = [ | |
sanitise_header(v) for v in msg.get_all(field) | |
] | |
else: | |
value = sanitise_header(msg.get(field)) | |
if key == "keywords": | |
# Accept both comma-separated and space-separated | |
# forms, for better compatibility with old data. | |
if "," in value: | |
value = [v.strip() for v in value.split(",")] | |
else: | |
value = value.split() | |
result[key] = value | |
payload = msg.get_payload() | |
if payload: | |
result["description"] = payload | |
return result | |