Исходный код soniks_client.models
"""Описание задания наблюдения, полученного от портала."""
from dataclasses import dataclass
from datetime import UTC, datetime
from core.types import TLE
[документация]
@dataclass
class JobData:
"""Задание наблюдения, полученное от портала."""
id: str
start: datetime
end: datetime
tle: TLE
frequency: int
mode: str
baud: int
norad_cat_id: int | None = None
[документация]
@classmethod
def from_dict(cls, job_data: dict[str, str | int | None]) -> "JobData":
"""Собрать задание из ответа API.
Args:
job_data: Словарь одного задания из ответа портала.
Returns:
Разобранное задание наблюдения.
"""
start = cls.parse_datetime(job_data["start"])
end = cls.parse_datetime(job_data["end"])
baud = job_data["baud"] or 0
tle = {
"tle0": job_data.get("tle0", ""),
"tle1": job_data.get("tle1", ""),
"tle2": job_data.get("tle2", ""),
}
return cls(
id=str(job_data["id"]),
start=start,
end=end,
tle=tle,
frequency=job_data["frequency"],
mode=job_data["mode"],
baud=baud,
norad_cat_id=job_data.get("norad_cat_id"),
)
[документация]
@staticmethod
def parse_datetime(datetime_str: str) -> datetime:
"""Разобрать метку времени из ответа портала в ``datetime`` с UTC."""
parsed = datetime.fromisoformat(datetime_str)
# Портал шлёт UTC; строка без смещения — форма записи, а не локальное
# время. Наивное значение роняло сверку расписания (сравнение с
# datetime.now(tz=UTC) в sync.py) и трактовалось APScheduler по зоне
# процесса, то есть проход планировался не на то время.
if parsed.tzinfo is None:
return parsed.replace(tzinfo=UTC)
return parsed.astimezone(UTC)
def __repr__(self) -> str:
start_str = self.start.strftime("%d-%m-%Y %H:%M (UTC)")
end_str = self.end.strftime("%d-%m-%Y %H:%M (UTC)")
tle0 = self.tle["tle0"]
satellite_name = tle0.removeprefix("0 ")
return (
f"JobData(id={self.id}, start={start_str}, end={end_str}, "
f"satellite_name={satellite_name}, frequency={self.frequency}, "
f"mode={self.mode}, baud={self.baud}, "
f"norad_cat_id={self.norad_cat_id})"
)