lghorizon 0.9.0__py3-none-any.whl → 0.9.0b0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lghorizon/__init__.py +2 -67
- lghorizon/exceptions.py +3 -3
- lghorizon/lghorizon_api.py +11 -41
- lghorizon/lghorizon_device.py +28 -101
- lghorizon/lghorizon_device_state_processor.py +26 -90
- lghorizon/lghorizon_message_factory.py +1 -0
- lghorizon/lghorizon_models.py +69 -250
- lghorizon/lghorizon_mqtt_client.py +66 -278
- lghorizon/lghorizon_recording_factory.py +2 -16
- lghorizon-0.9.0b0.dist-info/METADATA +41 -0
- lghorizon-0.9.0b0.dist-info/RECORD +17 -0
- lghorizon-0.9.0.dist-info/METADATA +0 -191
- lghorizon-0.9.0.dist-info/RECORD +0 -17
- {lghorizon-0.9.0.dist-info → lghorizon-0.9.0b0.dist-info}/WHEEL +0 -0
- {lghorizon-0.9.0.dist-info → lghorizon-0.9.0b0.dist-info}/licenses/LICENSE +0 -0
- {lghorizon-0.9.0.dist-info → lghorizon-0.9.0b0.dist-info}/top_level.txt +0 -0
lghorizon/lghorizon_models.py
CHANGED
|
@@ -8,7 +8,7 @@ import time
|
|
|
8
8
|
from abc import ABC, abstractmethod
|
|
9
9
|
from datetime import datetime
|
|
10
10
|
from enum import Enum
|
|
11
|
-
from typing import Any, Dict, List, Optional
|
|
11
|
+
from typing import Any, Dict, List, Optional
|
|
12
12
|
|
|
13
13
|
import backoff
|
|
14
14
|
from aiohttp import ClientResponseError, ClientSession
|
|
@@ -52,7 +52,7 @@ class LGHorizonRecordingState(Enum):
|
|
|
52
52
|
UNKNOWN = "unknown"
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
class LGHorizonRecordingType(Enum):
|
|
55
|
+
class LGHorizonRecordingType(Enum):
|
|
56
56
|
"""Enumeration of LG Horizon recording states."""
|
|
57
57
|
|
|
58
58
|
SINGLE = "single"
|
|
@@ -91,12 +91,6 @@ class LGHorizonMessage(ABC):
|
|
|
91
91
|
def __init__(self, topic: str, payload: dict) -> None:
|
|
92
92
|
"""Abstract base class for LG Horizon messages."""
|
|
93
93
|
self._topic = topic
|
|
94
|
-
"""Initialize the abstract base class for LG Horizon messages.
|
|
95
|
-
|
|
96
|
-
Args:
|
|
97
|
-
topic: The MQTT topic of the message.
|
|
98
|
-
payload: The dictionary payload of the message.
|
|
99
|
-
"""
|
|
100
94
|
self._payload = payload
|
|
101
95
|
|
|
102
96
|
def __repr__(self) -> str:
|
|
@@ -128,7 +122,7 @@ class LGHorizonStatusMessage(LGHorizonMessage):
|
|
|
128
122
|
|
|
129
123
|
|
|
130
124
|
class LGHorizonSourceType(Enum):
|
|
131
|
-
"""Enumeration of LG Horizon
|
|
125
|
+
"""Enumeration of LG Horizon message types."""
|
|
132
126
|
|
|
133
127
|
LINEAR = "linear"
|
|
134
128
|
REVIEWBUFFER = "reviewBuffer"
|
|
@@ -147,7 +141,7 @@ class LGHorizonSource(ABC):
|
|
|
147
141
|
|
|
148
142
|
@property
|
|
149
143
|
@abstractmethod
|
|
150
|
-
def source_type(self) -> LGHorizonSourceType:
|
|
144
|
+
def source_type(self) -> LGHorizonSourceType:
|
|
151
145
|
"""Return the message type."""
|
|
152
146
|
|
|
153
147
|
|
|
@@ -188,7 +182,7 @@ class LGHorizonReviewBufferSource(LGHorizonSource):
|
|
|
188
182
|
|
|
189
183
|
|
|
190
184
|
class LGHorizonNDVRSource(LGHorizonSource):
|
|
191
|
-
"""Represent the
|
|
185
|
+
"""Represent the ReviewBuffer Source of an LG Horizon device."""
|
|
192
186
|
|
|
193
187
|
@property
|
|
194
188
|
def recording_id(self) -> str:
|
|
@@ -229,7 +223,7 @@ class LGHorizonVODSource(LGHorizonSource):
|
|
|
229
223
|
|
|
230
224
|
|
|
231
225
|
class LGHorizonReplaySource(LGHorizonSource):
|
|
232
|
-
"""Represent the
|
|
226
|
+
"""Represent the VOD Source of an LG Horizon device."""
|
|
233
227
|
|
|
234
228
|
@property
|
|
235
229
|
def event_id(self) -> str:
|
|
@@ -243,7 +237,7 @@ class LGHorizonReplaySource(LGHorizonSource):
|
|
|
243
237
|
|
|
244
238
|
|
|
245
239
|
class LGHorizonUnknownSource(LGHorizonSource):
|
|
246
|
-
"""Represent
|
|
240
|
+
"""Represent the Linear Source of an LG Horizon device."""
|
|
247
241
|
|
|
248
242
|
@property
|
|
249
243
|
def source_type(self) -> LGHorizonSourceType:
|
|
@@ -274,13 +268,6 @@ class LGHorizonPlayerState:
|
|
|
274
268
|
"""Return the last speed change time."""
|
|
275
269
|
return self._raw_json.get("lastSpeedChangeTime", 0.0)
|
|
276
270
|
|
|
277
|
-
@property
|
|
278
|
-
def relative_position(
|
|
279
|
-
self,
|
|
280
|
-
) -> int:
|
|
281
|
-
"""Return the last speed change time."""
|
|
282
|
-
return self._raw_json.get("relativePosition", 0.0)
|
|
283
|
-
|
|
284
271
|
@property
|
|
285
272
|
def source(self) -> LGHorizonSource | None: # Added None to the return type
|
|
286
273
|
"""Return the last speed change time."""
|
|
@@ -301,7 +288,7 @@ class LGHorizonPlayerState:
|
|
|
301
288
|
|
|
302
289
|
|
|
303
290
|
class LGHorizonAppsState:
|
|
304
|
-
"""Represent the
|
|
291
|
+
"""Represent the State of an LG Horizon device."""
|
|
305
292
|
|
|
306
293
|
def __init__(self, raw_json: dict) -> None:
|
|
307
294
|
"""Initialize the Apps state."""
|
|
@@ -324,7 +311,7 @@ class LGHorizonAppsState:
|
|
|
324
311
|
|
|
325
312
|
|
|
326
313
|
class LGHorizonUIState:
|
|
327
|
-
"""Represent the
|
|
314
|
+
"""Represent the State of an LG Horizon device."""
|
|
328
315
|
|
|
329
316
|
_player_state: LGHorizonPlayerState | None = None
|
|
330
317
|
_apps_state: LGHorizonAppsState | None = None
|
|
@@ -332,11 +319,6 @@ class LGHorizonUIState:
|
|
|
332
319
|
def __init__(self, raw_json: dict) -> None:
|
|
333
320
|
"""Initialize the State."""
|
|
334
321
|
self._raw_json = raw_json
|
|
335
|
-
"""Initialize the UI State.
|
|
336
|
-
|
|
337
|
-
Args:
|
|
338
|
-
raw_json: The raw JSON dictionary containing UI state information.
|
|
339
|
-
"""
|
|
340
322
|
|
|
341
323
|
@property
|
|
342
324
|
def ui_status(self) -> LGHorizonUIStateType:
|
|
@@ -471,7 +453,6 @@ class LGHorizonAuth:
|
|
|
471
453
|
_country_code: str
|
|
472
454
|
_host: str
|
|
473
455
|
_use_refresh_token: bool
|
|
474
|
-
_token_refresh_callback: Callable[str, None] | None # pyright: ignore[reportInvalidTypeForm]
|
|
475
456
|
|
|
476
457
|
def __init__(
|
|
477
458
|
self,
|
|
@@ -493,7 +474,6 @@ class LGHorizonAuth:
|
|
|
493
474
|
self._host = COUNTRY_SETTINGS[country_code]["api_url"]
|
|
494
475
|
self._use_refresh_token = COUNTRY_SETTINGS[country_code]["use_refreshtoken"]
|
|
495
476
|
self._service_config = None
|
|
496
|
-
self._token_refresh_callback = None
|
|
497
477
|
|
|
498
478
|
@property
|
|
499
479
|
def websession(self) -> ClientSession:
|
|
@@ -609,8 +589,6 @@ class LGHorizonAuth:
|
|
|
609
589
|
self.household_id = auth_json["householdId"]
|
|
610
590
|
self.access_token = auth_json["accessToken"]
|
|
611
591
|
self.refresh_token = auth_json["refreshToken"]
|
|
612
|
-
if self._token_refresh_callback:
|
|
613
|
-
self._token_refresh_callback(self.refresh_token)
|
|
614
592
|
self.username = auth_json["username"]
|
|
615
593
|
self.token_expiry = auth_json["refreshTokenExpiry"]
|
|
616
594
|
|
|
@@ -691,16 +669,6 @@ class LGHorizonChannel:
|
|
|
691
669
|
"""Returns the channel number."""
|
|
692
670
|
return self.channel_json["logicalChannelNumber"]
|
|
693
671
|
|
|
694
|
-
@property
|
|
695
|
-
def replay_pre_padding(self) -> int:
|
|
696
|
-
"""Returns the channel number."""
|
|
697
|
-
return self.channel_json.get("replayPrePadding", 0)
|
|
698
|
-
|
|
699
|
-
@property
|
|
700
|
-
def replay_post_padding(self) -> int:
|
|
701
|
-
"""Returns the channel number."""
|
|
702
|
-
return self.channel_json.get("replayPostPadding", 0)
|
|
703
|
-
|
|
704
672
|
@property
|
|
705
673
|
def is_radio(self) -> bool:
|
|
706
674
|
"""Returns if the channel is a radio channel."""
|
|
@@ -852,44 +820,33 @@ class LGHorizonCustomer:
|
|
|
852
820
|
class LGHorizonDeviceState:
|
|
853
821
|
"""Represent current state of a box."""
|
|
854
822
|
|
|
855
|
-
_id: Optional[str]
|
|
856
823
|
_channel_id: Optional[str]
|
|
857
824
|
_channel_name: Optional[str]
|
|
858
|
-
|
|
859
|
-
_episode_title: Optional[str]
|
|
860
|
-
_season_number: Optional[int]
|
|
861
|
-
_episode_number: Optional[int]
|
|
825
|
+
_title: Optional[str]
|
|
862
826
|
_image: Optional[str]
|
|
863
827
|
_source_type: LGHorizonSourceType
|
|
864
828
|
_paused: bool
|
|
829
|
+
_sub_title: Optional[str]
|
|
865
830
|
_duration: Optional[float]
|
|
866
831
|
_position: Optional[float]
|
|
867
832
|
_last_position_update: Optional[datetime]
|
|
868
833
|
_state: LGHorizonRunningState
|
|
869
834
|
_speed: Optional[int]
|
|
870
|
-
_start_time: Optional[int]
|
|
871
|
-
_end_time: Optional[int]
|
|
872
835
|
|
|
873
836
|
def __init__(self) -> None:
|
|
874
837
|
"""Initialize the playing info."""
|
|
875
838
|
self._channel_id = None
|
|
876
|
-
self.
|
|
877
|
-
self._episode_title = None
|
|
878
|
-
self._season_number = None
|
|
879
|
-
self._episode_number = None
|
|
839
|
+
self._title = None
|
|
880
840
|
self._image = None
|
|
881
841
|
self._source_type = LGHorizonSourceType.UNKNOWN
|
|
882
|
-
self._ui_state_type = LGHorizonUIStateType.UNKNOWN
|
|
883
842
|
self._paused = False
|
|
843
|
+
self.sub_title = None
|
|
884
844
|
self._duration = None
|
|
885
845
|
self._position = None
|
|
886
846
|
self._last_position_update = None
|
|
887
847
|
self._state = LGHorizonRunningState.UNKNOWN
|
|
888
848
|
self._speed = None
|
|
889
849
|
self._channel_name = None
|
|
890
|
-
self._id = None
|
|
891
|
-
self._start_time = None
|
|
892
|
-
self._end_time = None
|
|
893
850
|
|
|
894
851
|
@property
|
|
895
852
|
def state(self) -> LGHorizonRunningState:
|
|
@@ -911,16 +868,6 @@ class LGHorizonDeviceState:
|
|
|
911
868
|
"""Set the channel ID."""
|
|
912
869
|
self._channel_id = value
|
|
913
870
|
|
|
914
|
-
@property
|
|
915
|
-
def id(self) -> Optional[str]:
|
|
916
|
-
"""Return the channel ID."""
|
|
917
|
-
return self._id
|
|
918
|
-
|
|
919
|
-
@id.setter
|
|
920
|
-
def id(self, value: Optional[str]) -> None:
|
|
921
|
-
"""Set the channel ID."""
|
|
922
|
-
self._id = value
|
|
923
|
-
|
|
924
871
|
@property
|
|
925
872
|
def channel_name(self) -> Optional[str]:
|
|
926
873
|
"""Return the channel ID."""
|
|
@@ -932,74 +879,14 @@ class LGHorizonDeviceState:
|
|
|
932
879
|
self._channel_name = value
|
|
933
880
|
|
|
934
881
|
@property
|
|
935
|
-
def
|
|
936
|
-
"""Return the title."""
|
|
937
|
-
return self._show_title
|
|
938
|
-
|
|
939
|
-
@show_title.setter
|
|
940
|
-
def show_title(self, value: Optional[str]) -> None:
|
|
941
|
-
"""Set the title."""
|
|
942
|
-
self._show_title = value
|
|
943
|
-
|
|
944
|
-
@property
|
|
945
|
-
def app_name(self) -> Optional[str]:
|
|
946
|
-
"""Return the title."""
|
|
947
|
-
return self._app_name
|
|
948
|
-
|
|
949
|
-
@app_name.setter
|
|
950
|
-
def app_name(self, value: Optional[str]) -> None:
|
|
951
|
-
"""Set the title."""
|
|
952
|
-
self._app_name = value
|
|
953
|
-
|
|
954
|
-
@property
|
|
955
|
-
def episode_title(self) -> Optional[str]:
|
|
956
|
-
"""Return the title."""
|
|
957
|
-
return self._episode_title
|
|
958
|
-
|
|
959
|
-
@episode_title.setter
|
|
960
|
-
def episode_title(self, value: Optional[str]) -> None:
|
|
961
|
-
"""Set the title."""
|
|
962
|
-
self._episode_title = value
|
|
963
|
-
|
|
964
|
-
@property
|
|
965
|
-
def episode_number(self) -> Optional[int]:
|
|
966
|
-
"""Return the title."""
|
|
967
|
-
return self._episode_number
|
|
968
|
-
|
|
969
|
-
@episode_number.setter
|
|
970
|
-
def episode_number(self, value: Optional[int]) -> None:
|
|
971
|
-
"""Set the title."""
|
|
972
|
-
self._episode_number = value
|
|
973
|
-
|
|
974
|
-
@property
|
|
975
|
-
def season_number(self) -> Optional[int]:
|
|
976
|
-
"""Return the title."""
|
|
977
|
-
return self._season_number
|
|
978
|
-
|
|
979
|
-
@season_number.setter
|
|
980
|
-
def season_number(self, value: Optional[int]) -> None:
|
|
981
|
-
"""Set the title."""
|
|
982
|
-
self._season_number = value
|
|
983
|
-
|
|
984
|
-
@property
|
|
985
|
-
def start_time(self) -> Optional[int]:
|
|
882
|
+
def title(self) -> Optional[str]:
|
|
986
883
|
"""Return the title."""
|
|
987
|
-
return self.
|
|
884
|
+
return self._title
|
|
988
885
|
|
|
989
|
-
@
|
|
990
|
-
def
|
|
886
|
+
@title.setter
|
|
887
|
+
def title(self, value: Optional[str]) -> None:
|
|
991
888
|
"""Set the title."""
|
|
992
|
-
self.
|
|
993
|
-
|
|
994
|
-
@property
|
|
995
|
-
def end_time(self) -> Optional[int]:
|
|
996
|
-
"""Return the title."""
|
|
997
|
-
return self._end_time
|
|
998
|
-
|
|
999
|
-
@end_time.setter
|
|
1000
|
-
def end_time(self, value: Optional[int]) -> None:
|
|
1001
|
-
"""Set the title."""
|
|
1002
|
-
self._end_time = value
|
|
889
|
+
self._title = value
|
|
1003
890
|
|
|
1004
891
|
@property
|
|
1005
892
|
def image(self) -> Optional[str]:
|
|
@@ -1021,16 +908,6 @@ class LGHorizonDeviceState:
|
|
|
1021
908
|
"""Set the source type."""
|
|
1022
909
|
self._source_type = value
|
|
1023
910
|
|
|
1024
|
-
@property
|
|
1025
|
-
def ui_state_type(self) -> LGHorizonUIStateType:
|
|
1026
|
-
"""Return the source type."""
|
|
1027
|
-
return self._ui_state_type
|
|
1028
|
-
|
|
1029
|
-
@ui_state_type.setter
|
|
1030
|
-
def ui_state_type(self, value: LGHorizonUIStateType) -> None:
|
|
1031
|
-
"""Set the source type."""
|
|
1032
|
-
self._ui_state_type = value
|
|
1033
|
-
|
|
1034
911
|
@property
|
|
1035
912
|
def paused(self) -> bool:
|
|
1036
913
|
"""Return if the media is paused."""
|
|
@@ -1038,6 +915,16 @@ class LGHorizonDeviceState:
|
|
|
1038
915
|
return False
|
|
1039
916
|
return self.speed == 0
|
|
1040
917
|
|
|
918
|
+
@property
|
|
919
|
+
def sub_title(self) -> Optional[str]:
|
|
920
|
+
"""Return the channel title."""
|
|
921
|
+
return self._sub_title
|
|
922
|
+
|
|
923
|
+
@sub_title.setter
|
|
924
|
+
def sub_title(self, value: Optional[str]) -> None:
|
|
925
|
+
"""Set the channel title."""
|
|
926
|
+
self._sub_title = value
|
|
927
|
+
|
|
1041
928
|
@property
|
|
1042
929
|
def duration(self) -> Optional[float]:
|
|
1043
930
|
"""Return the duration of the media."""
|
|
@@ -1059,12 +946,12 @@ class LGHorizonDeviceState:
|
|
|
1059
946
|
self._position = value
|
|
1060
947
|
|
|
1061
948
|
@property
|
|
1062
|
-
def last_position_update(self) -> Optional[
|
|
949
|
+
def last_position_update(self) -> Optional[datetime]:
|
|
1063
950
|
"""Return the last time the position was updated."""
|
|
1064
951
|
return self._last_position_update
|
|
1065
952
|
|
|
1066
953
|
@last_position_update.setter
|
|
1067
|
-
def last_position_update(self, value: Optional[
|
|
954
|
+
def last_position_update(self, value: Optional[datetime]) -> None:
|
|
1068
955
|
"""Set the last position update time."""
|
|
1069
956
|
self._last_position_update = value
|
|
1070
957
|
|
|
@@ -1087,18 +974,12 @@ class LGHorizonDeviceState:
|
|
|
1087
974
|
async def reset(self) -> None:
|
|
1088
975
|
"""Reset all playing information."""
|
|
1089
976
|
self.channel_id = None
|
|
1090
|
-
self.
|
|
1091
|
-
self.
|
|
1092
|
-
self.episode_title = None
|
|
1093
|
-
self.show_title = None
|
|
1094
|
-
self.app_name = None
|
|
977
|
+
self.title = None
|
|
978
|
+
self.sub_title = None
|
|
1095
979
|
self.image = None
|
|
1096
980
|
self.source_type = LGHorizonSourceType.UNKNOWN
|
|
1097
981
|
self.speed = None
|
|
1098
982
|
self.channel_name = None
|
|
1099
|
-
self.id = None
|
|
1100
|
-
self.start_time = None
|
|
1101
|
-
self.end_time = None
|
|
1102
983
|
await self.reset_progress()
|
|
1103
984
|
|
|
1104
985
|
|
|
@@ -1147,16 +1028,6 @@ class LGHorizonReplayEvent:
|
|
|
1147
1028
|
"""Return the season number."""
|
|
1148
1029
|
return self._raw_json.get("seasonNumber")
|
|
1149
1030
|
|
|
1150
|
-
@property
|
|
1151
|
-
def start_time(self) -> Optional[int]:
|
|
1152
|
-
"""Return the season number."""
|
|
1153
|
-
return self._raw_json.get("startTime", None)
|
|
1154
|
-
|
|
1155
|
-
@property
|
|
1156
|
-
def end_time(self) -> Optional[int]:
|
|
1157
|
-
"""Return the season number."""
|
|
1158
|
-
return self._raw_json.get("endTime", None)
|
|
1159
|
-
|
|
1160
1031
|
@property
|
|
1161
1032
|
def title(self) -> str:
|
|
1162
1033
|
"""Return the title of the event."""
|
|
@@ -1178,6 +1049,10 @@ class LGHorizonReplayEvent:
|
|
|
1178
1049
|
full_title += f": {self.episode_name}"
|
|
1179
1050
|
return full_title
|
|
1180
1051
|
|
|
1052
|
+
def __repr__(self) -> str:
|
|
1053
|
+
"""Return a string representation of the replay event."""
|
|
1054
|
+
return f"LGHorizonReplayEvent(title='{self.title}', channel_id='{self.channel_id}', event_id='{self.event_id}')"
|
|
1055
|
+
|
|
1181
1056
|
|
|
1182
1057
|
class LGHorizonVODType(Enum):
|
|
1183
1058
|
"""Enumeration of LG Horizon VOD types."""
|
|
@@ -1191,11 +1066,6 @@ class LGHorizonVOD:
|
|
|
1191
1066
|
"""LGHorizon video on demand."""
|
|
1192
1067
|
|
|
1193
1068
|
def __init__(self, vod_json) -> None:
|
|
1194
|
-
"""Initialize an LG Horizon VOD object.
|
|
1195
|
-
|
|
1196
|
-
Args:
|
|
1197
|
-
vod_json: The raw JSON dictionary containing VOD information.
|
|
1198
|
-
"""
|
|
1199
1069
|
self._vod_json = vod_json
|
|
1200
1070
|
|
|
1201
1071
|
@property
|
|
@@ -1209,14 +1079,26 @@ class LGHorizonVOD:
|
|
|
1209
1079
|
return self._vod_json["id"]
|
|
1210
1080
|
|
|
1211
1081
|
@property
|
|
1212
|
-
def
|
|
1082
|
+
def season_number(self) -> Optional[int]:
|
|
1213
1083
|
"""Return the season number of the recording."""
|
|
1214
|
-
return self._vod_json.get("
|
|
1084
|
+
return self._vod_json.get("seasonNumber", None)
|
|
1215
1085
|
|
|
1216
1086
|
@property
|
|
1217
|
-
def
|
|
1087
|
+
def episode_number(self) -> Optional[int]:
|
|
1218
1088
|
"""Return the episode number of the recording."""
|
|
1219
|
-
return self._vod_json.get("
|
|
1089
|
+
return self._vod_json.get("episodeNumber", None)
|
|
1090
|
+
|
|
1091
|
+
@property
|
|
1092
|
+
def full_episode_title(self) -> Optional[str]:
|
|
1093
|
+
"""Return the ID of the VOD."""
|
|
1094
|
+
if self.vod_type != LGHorizonVODType.EPISODE:
|
|
1095
|
+
return None
|
|
1096
|
+
if not self.season_number and not self.episode_number:
|
|
1097
|
+
return None
|
|
1098
|
+
full_title = f"""S{self.season_number:02d}E{self.episode_number:02d}"""
|
|
1099
|
+
if self.title:
|
|
1100
|
+
full_title += f": {self.title}"
|
|
1101
|
+
return full_title
|
|
1220
1102
|
|
|
1221
1103
|
@property
|
|
1222
1104
|
def title(self) -> str:
|
|
@@ -1235,7 +1117,7 @@ class LGHorizonVOD:
|
|
|
1235
1117
|
|
|
1236
1118
|
|
|
1237
1119
|
class LGHOrizonRelevantEpisode:
|
|
1238
|
-
"""
|
|
1120
|
+
"""LGHorizon recording."""
|
|
1239
1121
|
|
|
1240
1122
|
def __init__(self, episode_json: dict) -> None:
|
|
1241
1123
|
"""Abstract base class for LG Horizon recordings."""
|
|
@@ -1296,7 +1178,7 @@ class LGHorizonRecording(ABC):
|
|
|
1296
1178
|
@property
|
|
1297
1179
|
def title(self) -> str:
|
|
1298
1180
|
"""Return the title of the recording."""
|
|
1299
|
-
return self._recording_payload
|
|
1181
|
+
return self._recording_payload["title"]
|
|
1300
1182
|
|
|
1301
1183
|
@property
|
|
1302
1184
|
def channel_id(self) -> str:
|
|
@@ -1312,10 +1194,7 @@ class LGHorizonRecording(ABC):
|
|
|
1312
1194
|
return None
|
|
1313
1195
|
|
|
1314
1196
|
def __init__(self, recording_payload: dict) -> None:
|
|
1315
|
-
"""Abstract base class for LG Horizon recordings.
|
|
1316
|
-
Args:
|
|
1317
|
-
recording_payload: The raw JSON dictionary containing recording information.
|
|
1318
|
-
"""
|
|
1197
|
+
"""Abstract base class for LG Horizon recordings."""
|
|
1319
1198
|
self._recording_payload = recording_payload
|
|
1320
1199
|
|
|
1321
1200
|
|
|
@@ -1327,11 +1206,6 @@ class LGHorizonRecordingSingle(LGHorizonRecording):
|
|
|
1327
1206
|
"""Return the episode title of the recording."""
|
|
1328
1207
|
return self._recording_payload.get("episodeTitle", None)
|
|
1329
1208
|
|
|
1330
|
-
@property
|
|
1331
|
-
def episode_id(self) -> Optional[str]:
|
|
1332
|
-
"""Return the episode title of the recording."""
|
|
1333
|
-
return self._recording_payload.get("episodeId", None)
|
|
1334
|
-
|
|
1335
1209
|
@property
|
|
1336
1210
|
def season_number(self) -> Optional[int]:
|
|
1337
1211
|
"""Return the season number of the recording."""
|
|
@@ -1347,39 +1221,29 @@ class LGHorizonRecordingSingle(LGHorizonRecording):
|
|
|
1347
1221
|
"""Return the show ID of the recording."""
|
|
1348
1222
|
return self._recording_payload.get("showId", None)
|
|
1349
1223
|
|
|
1350
|
-
@property
|
|
1351
|
-
def show_title(self) -> Optional[str]:
|
|
1352
|
-
"""Return the show ID of the recording."""
|
|
1353
|
-
return self._recording_payload.get("showTitle", None)
|
|
1354
|
-
|
|
1355
1224
|
@property
|
|
1356
1225
|
def season_id(self) -> Optional[str]:
|
|
1357
1226
|
"""Return the season ID of the recording."""
|
|
1358
1227
|
return self._recording_payload.get("seasonId", None)
|
|
1359
1228
|
|
|
1229
|
+
@property
|
|
1230
|
+
def full_episode_title(self) -> Optional[str]:
|
|
1231
|
+
"""Return the full episode title of the recording."""
|
|
1232
|
+
if not self.season_number and not self.episode_number:
|
|
1233
|
+
return None
|
|
1234
|
+
full_title = f"""S{self.season_number:02d}E{self.episode_number:02d}"""
|
|
1235
|
+
if self.episode_title:
|
|
1236
|
+
full_title += f": {self.episode_title}"
|
|
1237
|
+
return full_title
|
|
1238
|
+
|
|
1360
1239
|
@property
|
|
1361
1240
|
def channel_id(self) -> Optional[str]:
|
|
1362
1241
|
"""Return the channel ID of the recording."""
|
|
1363
1242
|
return self._recording_payload.get("channelId", None)
|
|
1364
1243
|
|
|
1365
|
-
@property
|
|
1366
|
-
def duration(self) -> Optional[int]:
|
|
1367
|
-
"""Return the title."""
|
|
1368
|
-
return self.recording_payload.get("duration", None)
|
|
1369
|
-
|
|
1370
|
-
@property
|
|
1371
|
-
def start_time(self) -> Optional[int]:
|
|
1372
|
-
"""Return the title."""
|
|
1373
|
-
return self.recording_payload.get("startTime", None)
|
|
1374
|
-
|
|
1375
|
-
@property
|
|
1376
|
-
def end_time(self) -> Optional[int]:
|
|
1377
|
-
"""Return the title."""
|
|
1378
|
-
return self.recording_payload.get("endTime", None)
|
|
1379
|
-
|
|
1380
1244
|
|
|
1381
1245
|
class LGHorizonRecordingSeason(LGHorizonRecording):
|
|
1382
|
-
"""
|
|
1246
|
+
"""LGHorizon recording."""
|
|
1383
1247
|
|
|
1384
1248
|
_most_relevant_epsode: Optional[LGHOrizonRelevantEpisode]
|
|
1385
1249
|
|
|
@@ -1400,11 +1264,6 @@ class LGHorizonRecordingSeason(LGHorizonRecording):
|
|
|
1400
1264
|
"""Return the season title of the recording."""
|
|
1401
1265
|
return self._recording_payload.get("seasonTitle", "")
|
|
1402
1266
|
|
|
1403
|
-
@property
|
|
1404
|
-
def show_id(self) -> str:
|
|
1405
|
-
"""Return the season title of the recording."""
|
|
1406
|
-
return self._recording_payload.get("showId", "")
|
|
1407
|
-
|
|
1408
1267
|
@property
|
|
1409
1268
|
def most_relevant_episode(self) -> Optional[LGHOrizonRelevantEpisode]:
|
|
1410
1269
|
"""Return the most relevant episode of the season."""
|
|
@@ -1412,7 +1271,7 @@ class LGHorizonRecordingSeason(LGHorizonRecording):
|
|
|
1412
1271
|
|
|
1413
1272
|
|
|
1414
1273
|
class LGHorizonRecordingShow(LGHorizonRecording):
|
|
1415
|
-
"""
|
|
1274
|
+
"""LGHorizon recording."""
|
|
1416
1275
|
|
|
1417
1276
|
_most_relevant_epsode: Optional[LGHOrizonRelevantEpisode]
|
|
1418
1277
|
|
|
@@ -1435,7 +1294,7 @@ class LGHorizonRecordingShow(LGHorizonRecording):
|
|
|
1435
1294
|
|
|
1436
1295
|
|
|
1437
1296
|
class LGHorizonRecordingList:
|
|
1438
|
-
"""
|
|
1297
|
+
"""LGHorizon recording."""
|
|
1439
1298
|
|
|
1440
1299
|
@property
|
|
1441
1300
|
def total(self) -> int:
|
|
@@ -1443,49 +1302,9 @@ class LGHorizonRecordingList:
|
|
|
1443
1302
|
return len(self._recordings)
|
|
1444
1303
|
|
|
1445
1304
|
def __init__(self, recordings: List[LGHorizonRecording]) -> None:
|
|
1446
|
-
"""
|
|
1447
|
-
|
|
1448
|
-
Args:
|
|
1449
|
-
recordings: A list of LGHorizonRecording objects.
|
|
1450
|
-
"""
|
|
1305
|
+
"""Abstract base class for LG Horizon recordings."""
|
|
1451
1306
|
self._recordings = recordings
|
|
1452
1307
|
|
|
1453
|
-
@property
|
|
1454
|
-
def recordings(self) -> List[LGHorizonRecording]:
|
|
1455
|
-
"""Return the total number of recordings."""
|
|
1456
|
-
return self._recordings
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
class LGHorizonShowRecordingList(LGHorizonRecordingList):
|
|
1460
|
-
"""LGHorizon recording."""
|
|
1461
|
-
|
|
1462
|
-
def __init__(
|
|
1463
|
-
self,
|
|
1464
|
-
show_title: Optional[str],
|
|
1465
|
-
show_image,
|
|
1466
|
-
recordings: List[LGHorizonRecording],
|
|
1467
|
-
) -> None:
|
|
1468
|
-
"""Initialize an LG Horizon show recording list.
|
|
1469
|
-
|
|
1470
|
-
Args:
|
|
1471
|
-
show_title: The title of the show.
|
|
1472
|
-
show_image: The image URL for the show.
|
|
1473
|
-
recordings: A list of LGHorizonRecording objects belonging to the show.
|
|
1474
|
-
"""
|
|
1475
|
-
super().__init__(recordings)
|
|
1476
|
-
self._show_title = show_title
|
|
1477
|
-
self._show_image = show_image
|
|
1478
|
-
|
|
1479
|
-
@property
|
|
1480
|
-
def show_title(self) -> str:
|
|
1481
|
-
"""Title of the show."""
|
|
1482
|
-
return self._show_title
|
|
1483
|
-
|
|
1484
|
-
@property
|
|
1485
|
-
def show_image(self) -> Optional[str]:
|
|
1486
|
-
"""Image of the show."""
|
|
1487
|
-
return self._show_image
|
|
1488
|
-
|
|
1489
1308
|
|
|
1490
1309
|
class LGHorizonRecordingQuota:
|
|
1491
1310
|
"""LGHorizon recording quota."""
|