# Copyright Mozilla Foundation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License.
from __future__ import annotations
from enum import Enum from io import BytesIO from json import JSONDecodeError, loads from os.path import splitext from typing import Any
bilingual_extensions = { ".po", ".pot", ".xlf", ".xliff",
} """
Extensions used by file formats (XLIFF & gettext) that contain
both the reference and target languages in the same file. """
def detect_format(name: str | None, source: bytes | str) -> Format | None: """
Detect the format of the input based on its file extension and/or contents.
Returns a `Format` enum value, or `None` if the input isnot recognized. """ ifnot name:
ext = None else:
_, ext = splitext(name) if ext == ".dtd": return Format.dtd elif ext == ".ftl": return Format.fluent elif ext == ".inc": return Format.inc elif ext == ".ini": return Format.ini elif ext == ".properties": return Format.properties elif ext in {".po", ".pot"}: return Format.po elif ext in {".xlf", ".xliff"}: return Format.xliff
# Try parsing as JSON first, unless we're pretty sure it's XML if ext != ".xml": try:
json: dict[str, Any] = loads(source) ifnot is_object_of_strings(json): returnNone if all(is_webext_message(m) for m in json.values()): return Format.webext return Format.plain_json except JSONDecodeError: pass
# Let's presume the input is XML and look at its root node. try: from lxml.etree import LxmlError, iterparse
bs = source.encode() if isinstance(source, str) else source
_, xml_root = next(iterparse(BytesIO(bs), events=("start",)))
ns = xml_root.nsmap.get(None, None) if ns: return Format.xliff if ns in xliff_ns elseNone return Format.android if xml_root.tag == "resources"elseNone except ImportError: pass except LxmlError: # Must be separate and after ImportError pass
returnNone
def is_object_of_strings(obj: Any) -> bool: ifnot isinstance(obj, dict): returnFalse for value in obj.values(): if isinstance(value, dict): ifnot is_object_of_strings(value): returnFalse elifnot isinstance(value, str): returnFalse returnTrue
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.