Ejemplo n.º 1
0
class NmeaInjectorSettingsSpecV1(pykson.JsonObject):
    kind = pykson.StringField()
    port = pykson.IntegerField()
    component_id = pykson.IntegerField()

    def __eq__(self, other: object) -> Any:
        if isinstance(other, NmeaInjectorSettingsSpecV1):
            return self.kind == other.kind and self.port == other.port
        return False
Ejemplo n.º 2
0
class BridgeSettingsSpecV1(pykson.JsonObject):
    serial_path = pykson.StringField()
    baudrate = pykson.IntegerField()
    ip = pykson.StringField()
    udp_port = pykson.IntegerField()

    @staticmethod
    def from_spec(spec: "BridgeSpec") -> "BridgeSettingsSpecV1":  # type: ignore
        return BridgeSettingsSpecV1(
            serial_path=spec.serial_path,
            baudrate=spec.baud,
            ip=spec.ip,
            udp_port=spec.udp_port,
        )

    def __eq__(self, other: object) -> Any:
        if isinstance(other, BridgeSettingsSpecV1):
            return self.serial_path == other.serial_path
        return False
Ejemplo n.º 3
0
class SettingsV12(SettingsV3):
    VERSION = 12
    version_12_variable = pykson.IntegerField(default_value=1992)

    def __init__(self, *args: str, **kwargs: int) -> None:
        super().__init__(*args, **kwargs)

        self.VERSION = SettingsV12.VERSION

    def migrate(self, data: Dict[str, Any]) -> None:
        if data["VERSION"] == SettingsV12.VERSION:
            return

        if data["VERSION"] < SettingsV12.VERSION:
            SettingsV3().migrate(data)

        data["VERSION"] = SettingsV12.VERSION
        data["version_12_variable"] = self.version_12_variable
class SettingsV1(settings.BaseSettings):
    VERSION = 1
    animal = pykson.ObjectField(Animal, default_value=Animal("bilica", "dog"))
    first_variable = pykson.IntegerField(default_value=42)

    def __init__(self, *args: str, **kwargs: int) -> None:
        super().__init__(*args, **kwargs)

        self.VERSION = SettingsV1.VERSION

    def migrate(self, data: Dict[str, Any]) -> None:
        if data["VERSION"] == SettingsV1.VERSION:
            return

        if data["VERSION"] < SettingsV1.VERSION:
            super().migrate(data)

        data["VERSION"] = SettingsV1.VERSION
        data["animal"] = self.animal
        data["first_variable"] = self.first_variable
class SettingsV2(settings.BaseSettings):
    VERSION = 2
    first_variable = pykson.IntegerField(default_value=66)
    new_animal_name = pykson.ObjectField(Animal,
                                         default_value=Animal("bilica", "dog"))

    def __init__(self, *args: str, **kwargs: int) -> None:
        super().__init__(*args, **kwargs)

        self.VERSION = SettingsV2.VERSION

    def migrate(self, data: Dict[str, Any]) -> None:
        if data["VERSION"] == SettingsV2.VERSION:
            return

        if data["VERSION"] < SettingsV2.VERSION:
            SettingsV1().migrate(data)

        data["VERSION"] = SettingsV2.VERSION
        data["first_variable"] = self.first_variable

        # Update variable name
        data["new_animal_name"] = data["animal"]
        data.pop("animal")
Ejemplo n.º 6
0
class BaseSettings(pykson.JsonObject):
    """Base settings class that has version control and struct based serialization/deserialization"""

    VERSION = pykson.IntegerField(default_value=0)

    def __init__(self, *args: str, **kwargs: int) -> None:
        super().__init__(*args, **kwargs)

    @abc.abstractmethod
    def migrate(self, data: Dict[str, Any]) -> None:
        """Function used to migrate from previous settings verion

        Args:
            data (dict): Data from the previous version settings
        """
        raise RuntimeError("Migrating the setings file does not appears to be possible.")

    def load(self, file_path: pathlib.Path) -> None:
        """Load settings from file

        Args:
            file_path (pathlib.Path): Path for settings file
        """
        if not file_path.exists():
            raise RuntimeError(f"Settings file does not exist: {file_path}")

        logger.debug(f"Loading settings from file: {file_path}")
        with open(file_path, encoding="utf-8") as settings_file:
            result = json.load(settings_file)

            if "VERSION" not in result.keys():
                raise BadSettingsFile(f"Settings file does not appears to contain a valid settings format: {result}")

            version = result["VERSION"]

            if version <= 0:
                raise BadAttributes("Settings file contains invalid version number")

            if version > self.VERSION:
                raise SettingsFromTheFuture(
                    f"Settings file comes from a future settings version: {version}, "
                    f"latest supported: {self.VERSION}, tomorrow does not exist"
                )

            if version < self.VERSION:
                self.migrate(result)
                version = result["VERSION"]

            if version != self.VERSION:
                raise MigrationFail("Migrate chain failed to update to the latest settings version available")

            # Copy new content to settings class
            new = Pykson().from_json(result, self.__class__)
            self.__dict__.update(new.__dict__)

    def save(self, file_path: pathlib.Path) -> None:
        """Save settings to file

        Args:
            file_path (pathlib.Path): Path for the settings file
        """
        # Path for settings file does not exist, lets ensure that it does
        parent_path = file_path.parent.absolute()
        parent_path.mkdir(parents=True, exist_ok=True)

        with open(file_path, "w", encoding="utf-8") as settings_file:
            logger.debug(f"Saving settings on: {file_path}")
            settings_file.write(Pykson().to_json(self))

    def reset(self) -> None:
        """Reset internal data to default values"""
        logger.debug("Resetting settings")
        new = self.__class__()
        self.__dict__.update(new.__dict__)
class SettingsV1Expanded(SettingsV1):
    new_variable = pykson.IntegerField(default_value=1992)