Source code for ucsschool.import_lusd.reader
import json
from typing import Any, Dict, Generator
from ucsschool.importer.exceptions import ConfigurationError
from ucsschool.importer.models.import_user import ImportUser
from ucsschool.importer.reader.csv_reader import CsvReader
[docs]
class LUSDReader(CsvReader): # type: ignore[misc]
def __init__(self, filename: str, header_lines: int = 0, **kwargs: Any) -> None:
"""
:param str filename: Path to file with user data.
:param int header_lines: Number of lines before the actual data starts.
:param dict kwargs: optional parameters for use in derived classes
"""
super().__init__(filename, header_lines, **kwargs)
self.config["csv"] = self.config["lusd"]
self._delimiter: str = self.config["csv"].get("incell-delimiter", {}).get("default", ",")
[docs]
def read(self) -> Generator[Dict[str, str], None, None]:
"""
Generate dicts from a JSON file.
:return: iterator over list of dicts
:rtype: Generator[Dict[str, str], None, None]
"""
with open(self.filename) as fp:
self.logger.debug("Reading %r.", self.filename)
json_data = json.load(fp)[0]["antwort"][self.config["lusd"]["lusd_user_type"]]
try:
self.fieldnames = json_data[0].keys()
except IndexError:
self.logger.warning("No users in %r.", self.filename)
self.fieldnames = []
return
missing_attributes = self._get_missing_columns()
# see LUSD specification
optional_attrs = ["klassenname"]
if missing_attributes and not all(attr in optional_attrs for attr in missing_attributes):
raise ConfigurationError(
"Attributes configured in csv:mapping missing: "
"{!r}. Attributes found: {!r}".format(missing_attributes, self.fieldnames)
)
user_obj: Dict[str, Any]
for idx, user_obj in enumerate(json_data):
self.entry_count = idx + 1
self.input_data = user_obj
self.lusd_preprocessing(user_obj)
yield user_obj
[docs]
def lusd_preprocessing(self, user_obj: Dict[str, Any]) -> None:
"""Convert LUSD API attributes which are arrays to string to be conform with the CsvReader"""
for attr in ["klassenlehrerKlassen", "klassenlehrerVertreterKlassen"]:
if attr in user_obj:
user_obj[attr] = self._delimiter.join(
[
class_obj["klassenname"].replace(
self._delimiter,
self.config.get("school_classes_invalid_character_replacement", ""),
)
for class_obj in user_obj[attr]
if "klassenname" in class_obj
]
)
if "klassenname" not in user_obj and "schuelerUID" in user_obj:
user_obj["klassenname"] = "lusd_noclass"