lghorizon 0.9.0__py3-none-any.whl → 0.9.0.dev1__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 CHANGED
@@ -1,71 +1,36 @@
1
1
  """Python client for LG Horizon."""
2
2
 
3
- from .lghorizon_api import LGHorizonApi
4
- from .lghorizon_device import LGHorizonDevice
5
- from .lghorizon_models import (
3
+ from .lghorizonapi import LGHorizonApi
4
+ from .models.lghorizon_auth import (
6
5
  LGHorizonAuth,
7
- LGHorizonChannel,
8
- LGHorizonCustomer,
9
- LGHorizonDeviceState,
10
- LGHorizonProfile,
11
- LGHorizonRecording,
12
- LGHorizonRecordingList,
13
- LGHorizonShowRecordingList,
14
- LGHorizonRecordingSeason,
15
- LGHorizonRecordingSingle,
16
- LGHorizonRecordingShow,
17
- LGHorizonRecordingQuota,
18
- LGHorizonRecordingType,
19
- LGHorizonUIStateType,
20
- LGHorizonMessageType,
21
- LGHorizonRunningState,
22
- LGHorizonRecordingSource,
23
- LGHorizonRecordingState,
24
- LGHorizonSourceType,
25
- LGHorizonPlayerState,
26
- LGHorizonAppsState,
27
- LGHorizonUIState,
28
- LGHorizonProfileOptions,
29
- LGHorizonServicesConfig,
30
6
  )
31
- from .exceptions import (
32
- LGHorizonApiError,
33
- LGHorizonApiConnectionError,
7
+ from .models.exceptions import (
34
8
  LGHorizonApiUnauthorizedError,
9
+ LGHorizonApiConnectionError,
35
10
  LGHorizonApiLockedError,
36
11
  )
12
+ from .const import (
13
+ ONLINE_RUNNING,
14
+ ONLINE_STANDBY,
15
+ RECORDING_TYPE_SHOW,
16
+ RECORDING_TYPE_SEASON,
17
+ RECORDING_TYPE_SINGLE,
18
+ )
37
19
 
38
20
  __all__ = [
39
21
  "LGHorizonApi",
40
- "LGHorizonDevice",
41
- "LGHorizonAuth",
42
- "LGHorizonChannel",
22
+ "LGHorizonBox",
23
+ "LGHorizonRecordingListSeasonShow",
24
+ "LGHorizonRecordingSingle",
25
+ "LGHorizonRecordingShow",
26
+ "LGHorizonRecordingEpisode",
43
27
  "LGHorizonCustomer",
44
- "LGHorizonDeviceState",
45
- "LGHorizonProfile",
46
- "LGHorizonApiError",
47
- "LGHorizonApiConnectionError",
48
28
  "LGHorizonApiUnauthorizedError",
29
+ "LGHorizonApiConnectionError",
49
30
  "LGHorizonApiLockedError",
50
- "LGHorizonRecordingList",
51
- "LGHorizonRecordingSeason",
52
- "LGHorizonRecordingSingle",
53
- "LGHorizonRecordingShow",
54
- "LGHorizonRecordingQuota",
55
- "LGHorizonRecordingType",
56
- "LGHorizonUIStateType",
57
- "LGHorizonMessageType",
58
- "LGHorizonRunningState",
59
- "LGHorizonRecordingSource",
60
- "LGHorizonRecordingState",
61
- "LGHorizonSourceType",
62
- "LGHorizonPlayerState",
63
- "LGHorizonAppsState",
64
- "LGHorizonUIState",
65
- "LGHorizonProfileOptions",
66
- "LGHorizonProfile",
67
- "LGHorizonAuth",
68
- "LGHorizonServicesConfig",
69
- "LGHorizonRecording",
70
- "LGHorizonShowRecordingList",
71
- ]
31
+ "ONLINE_RUNNING",
32
+ "ONLINE_STANDBY",
33
+ "RECORDING_TYPE_SHOW",
34
+ "RECORDING_TYPE_SEASON",
35
+ "RECORDING_TYPE_SINGLE",
36
+ ] # noqa
@@ -3,34 +3,33 @@
3
3
  import random
4
4
  import json
5
5
  import urllib.parse
6
- from datetime import datetime as dt, timezone
7
-
8
- import time
9
6
 
10
7
  from typing import cast, Dict, Optional
11
8
 
12
- from .lghorizon_models import LGHorizonDeviceState, LGHorizonRunningState
13
- from .lghorizon_models import LGHorizonStatusMessage, LGHorizonUIStatusMessage
14
- from .lghorizon_models import (
9
+ from .models.lghorizon_device_state import LGHorizonDeviceState, LGHorizonRunningState
10
+ from .models.lghorizon_message import LGHorizonStatusMessage, LGHorizonUIStatusMessage
11
+ from .models.lghorizon_sources import (
15
12
  LGHorizonSourceType,
16
13
  LGHorizonLinearSource,
17
14
  LGHorizonVODSource,
18
15
  LGHorizonReplaySource,
19
16
  LGHorizonNDVRSource,
20
17
  LGHorizonReviewBufferSource,
21
- LGHorizonRecordingSource,
22
18
  )
23
- from .lghorizon_models import LGHorizonAuth
24
- from .lghorizon_models import LGHorizonReplayEvent, LGHorizonVOD, LGHorizonVODType
19
+ from .models.lghorizon_auth import LGHorizonAuth
20
+ from .models.lghorizon_events import (
21
+ LGHorizonReplayEvent,
22
+ LGHorizonVOD,
23
+ )
25
24
 
26
- from .lghorizon_models import LGHorizonRecordingSingle
27
- from .lghorizon_models import LGHorizonChannel
28
- from .lghorizon_models import (
25
+ from .models.lghorizon_recordings import LGHorizonRecordingSingle
26
+ from .models.lghorizon_channel import LGHorizonChannel
27
+ from .models.lghorizon_ui_status import (
29
28
  LGHorizonUIStateType,
30
29
  LGHorizonAppsState,
31
30
  LGHorizonPlayerState,
32
31
  )
33
- from .lghorizon_models import LGHorizonCustomer
32
+ from .models.lghorizon_customer import LGHorizonCustomer
34
33
 
35
34
 
36
35
  class LGHorizonDeviceStateProcessor:
@@ -100,9 +99,6 @@ class LGHorizonDeviceStateProcessor:
100
99
  return
101
100
  await device_state.reset()
102
101
  device_state.source_type = player_state.source_type
103
- device_state.ui_state_type = LGHorizonUIStateType.MAINUI
104
- device_state.speed = player_state.speed
105
-
106
102
  match player_state.source_type:
107
103
  case LGHorizonSourceType.LINEAR:
108
104
  await self._process_linear_state(device_state, player_state)
@@ -120,10 +116,9 @@ class LGHorizonDeviceStateProcessor:
120
116
  device_state: LGHorizonDeviceState,
121
117
  apps_state: LGHorizonAppsState,
122
118
  ) -> None:
123
- device_state.id = apps_state.id
124
- device_state.show_title = apps_state.app_name
119
+ device_state.channel_id = apps_state.id
120
+ device_state.title = apps_state.app_name
125
121
  device_state.image = apps_state.logo_path
126
- device_state.ui_state_type = LGHorizonUIStateType.APPS
127
122
 
128
123
  async def _process_linear_state(
129
124
  self,
@@ -145,22 +140,12 @@ class LGHorizonDeviceStateProcessor:
145
140
  service_path,
146
141
  )
147
142
  replay_event = LGHorizonReplayEvent(event_json)
148
- device_state.id = replay_event.event_id
149
143
  channel = self._channels[replay_event.channel_id]
150
144
  device_state.source_type = source.source_type
151
- device_state.channel_id = channel.id
145
+ device_state.channel_id = channel.channel_number
152
146
  device_state.channel_name = channel.title
153
- device_state.episode_title = replay_event.episode_name
154
- device_state.season_number = replay_event.season_number
155
- device_state.episode_number = replay_event.episode_number
156
- device_state.show_title = replay_event.title
157
- now_in_ms = int(time.time() * 1000)
158
-
159
- device_state.last_position_update = int(time.time() * 1000)
160
- device_state.start_time = replay_event.start_time
161
- device_state.end_time = replay_event.end_time
162
- device_state.duration = replay_event.end_time - replay_event.start_time
163
- device_state.position = now_in_ms - int(replay_event.start_time * 1000)
147
+ device_state.title = replay_event.title
148
+ device_state.sub_title = replay_event.full_episode_title
164
149
 
165
150
  # Add random number to url to force refresh
166
151
  join_param = "?"
@@ -170,6 +155,7 @@ class LGHorizonDeviceStateProcessor:
170
155
  f"{channel.stream_image}{join_param}{str(random.randrange(1000000))}"
171
156
  )
172
157
  device_state.image = image_url
158
+ await device_state.reset_progress()
173
159
 
174
160
  async def _process_reviewbuffer_state(
175
161
  self,
@@ -191,20 +177,13 @@ class LGHorizonDeviceStateProcessor:
191
177
  service_path,
192
178
  )
193
179
  replay_event = LGHorizonReplayEvent(event_json)
194
- device_state.id = replay_event.event_id
195
180
  channel = self._channels[replay_event.channel_id]
196
181
  device_state.source_type = source.source_type
197
- device_state.channel_id = channel.id
182
+ device_state.channel_id = channel.channel_number
198
183
  device_state.channel_name = channel.title
199
- device_state.episode_title = replay_event.episode_name
200
- device_state.season_number = replay_event.season_number
201
- device_state.episode_number = replay_event.episode_number
202
- device_state.show_title = replay_event.title
203
- device_state.last_position_update = player_state.last_speed_change_time
204
- device_state.position = player_state.relative_position
205
- device_state.start_time = replay_event.start_time
206
- device_state.end_time = replay_event.end_time
207
- device_state.duration = replay_event.end_time - replay_event.start_time
184
+ device_state.title = replay_event.title
185
+ device_state.sub_title = replay_event.full_episode_title
186
+
208
187
  # Add random number to url to force refresh
209
188
  join_param = "?"
210
189
  if join_param in channel.stream_image:
@@ -213,6 +192,7 @@ class LGHorizonDeviceStateProcessor:
213
192
  f"{channel.stream_image}{join_param}{str(random.randrange(1000000))}"
214
193
  )
215
194
  device_state.image = image_url
195
+ await device_state.reset_progress()
216
196
 
217
197
  async def _process_replay_state(
218
198
  self,
@@ -234,27 +214,15 @@ class LGHorizonDeviceStateProcessor:
234
214
  service_path,
235
215
  )
236
216
  replay_event = LGHorizonReplayEvent(event_json)
237
- device_state.id = replay_event.event_id
238
- # Iets met buffer doen
239
- channel = self._channels[replay_event.channel_id]
240
- padding = channel.replay_pre_padding + channel.replay_post_padding
241
217
  device_state.source_type = source.source_type
242
- device_state.channel_id = channel.id
243
- device_state.episode_title = replay_event.episode_name
244
- device_state.season_number = replay_event.season_number
245
- device_state.episode_number = replay_event.episode_number
246
- device_state.show_title = replay_event.title
247
- device_state.last_position_update = int(time.time() * 1000)
248
- device_state.start_time = replay_event.start_time
249
- device_state.end_time = replay_event.end_time
250
- device_state.duration = (
251
- replay_event.end_time - replay_event.start_time + padding
252
- )
253
- device_state.position = (
254
- player_state.relative_position + channel.replay_pre_padding
255
- )
218
+ device_state.channel_id = None
219
+ device_state.title = replay_event.title
220
+ if replay_event.full_episode_title:
221
+ device_state.sub_title = replay_event.full_episode_title
222
+
256
223
  # Add random number to url to force refresh
257
224
  device_state.image = await self._get_intent_image_url(replay_event.event_id)
225
+ await device_state.reset_progress()
258
226
 
259
227
  async def _process_vod_state(
260
228
  self,
@@ -276,20 +244,11 @@ class LGHorizonDeviceStateProcessor:
276
244
  service_path,
277
245
  )
278
246
  vod = LGHorizonVOD(vod_json)
279
- device_state.id = vod.id
280
- if vod.vod_type == LGHorizonVODType.EPISODE:
281
- device_state.show_title = vod.series_title
282
- device_state.episode_title = vod.title
283
- device_state.season_number = vod.season
284
- device_state.episode_number = vod.episode
285
- else:
286
- device_state.show_title = vod.title
287
-
247
+ device_state.title = vod.title
248
+ device_state.sub_title = vod.full_episode_title
288
249
  device_state.duration = vod.duration
289
- device_state.last_position_update = int(time.time() * 1000)
290
- device_state.position = player_state.relative_position
291
-
292
250
  device_state.image = await self._get_intent_image_url(vod.id)
251
+ await device_state.reset_progress()
293
252
 
294
253
  async def _process_ndvr_state(
295
254
  self, device_state: LGHorizonDeviceState, player_state: LGHorizonPlayerState
@@ -308,36 +267,13 @@ class LGHorizonDeviceStateProcessor:
308
267
  service_path,
309
268
  )
310
269
  recording = LGHorizonRecordingSingle(recording_json)
311
- device_state.id = recording.id
270
+ device_state.title = recording.title
271
+ device_state.sub_title = recording.full_episode_title
312
272
  device_state.channel_id = recording.channel_id
313
273
  if recording.channel_id:
314
274
  channel = self._channels[recording.channel_id]
315
275
  device_state.channel_name = channel.title
316
276
 
317
- device_state.episode_title = recording.episode_title
318
- device_state.season_number = recording.season_number
319
- device_state.episode_number = recording.episode_number
320
- device_state.last_position_update = player_state.last_speed_change_time
321
- device_state.position = player_state.relative_position
322
- if recording.start_time:
323
- device_state.start_time = int(
324
- dt.fromisoformat(
325
- recording.start_time.replace("Z", "+00:00")
326
- ).timestamp()
327
- )
328
- if recording.end_time:
329
- device_state.end_time = int(
330
- dt.fromisoformat(recording.end_time.replace("Z", "+00:00")).timestamp()
331
- )
332
- if recording.start_time and recording.end_time:
333
- device_state.duration = device_state.end_time - device_state.start_time
334
- if recording.source == LGHorizonRecordingSource.SHOW:
335
- device_state.show_title = recording.title
336
- else:
337
- device_state.show_title = recording.show_title
338
-
339
- device_state.image = await self._get_intent_image_url(recording.id)
340
-
341
277
  async def _get_intent_image_url(self, intent_id: str) -> Optional[str]:
342
278
  """Get intent image url."""
343
279
  service_config = await self._auth.get_service_config()
@@ -1,27 +1,23 @@
1
1
  """LG Horizon API client."""
2
2
 
3
3
  import logging
4
- from typing import Any, Dict, cast, Callable, Optional
5
-
6
- from .lghorizon_device import LGHorizonDevice
7
- from .lghorizon_models import LGHorizonChannel
8
- from .lghorizon_models import LGHorizonAuth
9
- from .lghorizon_models import LGHorizonCustomer
10
- from .lghorizon_mqtt_client import LGHorizonMqttClient
11
- from .lghorizon_models import LGHorizonServicesConfig
12
- from .lghorizon_models import LGHorizonEntitlements
13
- from .lghorizon_models import LGHorizonProfile
14
- from .lghorizon_models import LGHorizonMessageType
15
- from .lghorizon_message_factory import LGHorizonMessageFactory
16
- from .lghorizon_models import LGHorizonStatusMessage, LGHorizonUIStatusMessage
17
- from .lghorizon_models import LGHorizonRunningState
18
- from .lghorizon_models import (
19
- LGHorizonRecordingList,
20
- LGHorizonRecordingQuota,
21
- LGHorizonShowRecordingList,
22
- )
23
- from .lghorizon_recording_factory import LGHorizonRecordingFactory
24
- from .lghorizon_device_state_processor import LGHorizonDeviceStateProcessor
4
+ from typing import Any, Dict, cast
5
+
6
+ from .models.lghorizon_device import LGHorizonDevice
7
+ from .models.lghorizon_channel import LGHorizonChannel
8
+ from .models.lghorizon_auth import LGHorizonAuth
9
+ from .models.lghorizon_customer import LGHorizonCustomer
10
+ from .models.lghorizon_mqtt_client import LGHorizonMqttClient
11
+ from .models.lghorizon_config import LGHorizonServicesConfig
12
+ from .models.lghorizon_entitlements import LGHorizonEntitlements
13
+ from .models.lghorizon_profile import LGHorizonProfile
14
+ from .models.lghorizon_message import LGHorizonMessageType
15
+ from .message_factory import LGHorizonMessageFactory
16
+ from .models.lghorizon_message import LGHorizonStatusMessage, LGHorizonUIStatusMessage
17
+ from .models.lghorizon_device_state import LGHorizonRunningState
18
+ from .models.lghorizon_recordings import LGHorizonRecordingList, LGHorizonRecordingQuota
19
+ from .recording_factory import LGHorizonRecordingFactory
20
+ from .device_state_processor import LGHorizonDeviceStateProcessor
25
21
 
26
22
 
27
23
  _LOGGER = logging.getLogger(__name__)
@@ -30,7 +26,7 @@ _LOGGER = logging.getLogger(__name__)
30
26
  class LGHorizonApi:
31
27
  """LG Horizon API client."""
32
28
 
33
- _mqtt_client: LGHorizonMqttClient | None
29
+ _mqtt_client: LGHorizonMqttClient
34
30
  auth: LGHorizonAuth
35
31
  _service_config: LGHorizonServicesConfig
36
32
  _customer: LGHorizonCustomer
@@ -45,18 +41,10 @@ class LGHorizonApi:
45
41
 
46
42
  def __init__(self, auth: LGHorizonAuth, profile_id: str = "") -> None:
47
43
  """Initialize LG Horizon API client."""
48
- """Initialize LG Horizon API client.
49
-
50
- Args:
51
- auth: The authentication object for API requests.
52
- profile_id: The ID of the user profile to use (optional).
53
- """
54
44
  self.auth = auth
55
45
  self._profile_id = profile_id
56
46
  self._channels = {}
57
47
  self._device_state_processor = None
58
- self._mqtt_client = None
59
- self._initialized = False
60
48
 
61
49
  async def initialize(self) -> None:
62
50
  """Initialize the API client."""
@@ -74,20 +62,14 @@ class LGHorizonApi:
74
62
  )
75
63
  self._initialized = True
76
64
 
77
- async def set_token_refresh_callback(
78
- self, token_refresh_callback: Callable[str, None]
79
- ) -> None:
80
- """Set the token refresh callback."""
81
- self.auth.token_refresh_callback = token_refresh_callback
82
-
83
- async def get_devices(self) -> dict[str, LGHorizonDevice]:
65
+ async def get_devices(self) -> Dict[str, LGHorizonDevice]:
84
66
  """Get devices."""
85
67
  if not self._initialized:
86
68
  raise RuntimeError("LGHorizonApi not initialized")
87
69
 
88
70
  return self._devices
89
71
 
90
- async def get_profiles(self) -> dict[str, LGHorizonProfile]:
72
+ async def get_profiles(self) -> Dict[str, LGHorizonProfile]:
91
73
  """Get profile IDs."""
92
74
  if not self._initialized:
93
75
  raise RuntimeError("LGHorizonApi not initialized")
@@ -95,16 +77,14 @@ class LGHorizonApi:
95
77
  return self._customer.profiles
96
78
 
97
79
  async def get_profile_channels(
98
- self, profile_id: Optional[str] = None
80
+ self, profile_id: str
99
81
  ) -> Dict[str, LGHorizonChannel]:
100
82
  """Returns channels to display baed on profile."""
101
83
  # Attempt to retrieve the profile by the given profile_id
102
- if not profile_id:
103
- profile_id = self._profile_id
104
84
  profile = self._customer.profiles.get(profile_id)
105
85
 
106
86
  # If the specified profile is not found, and there are other profiles available,
107
- # default to the first profile in the customer's list if available.
87
+ # default to the first profile in the customer's list.
108
88
  if not profile and self._customer.profiles:
109
89
  _LOGGER.debug(
110
90
  "Profile with ID '%s' not found. Defaulting to first available profile.",
@@ -155,10 +135,6 @@ class LGHorizonApi:
155
135
  self._initialized = False
156
136
 
157
137
  async def _create_mqtt_client(self) -> LGHorizonMqttClient:
158
- """Create and configure the MQTT client.
159
-
160
- Returns: An initialized LGHorizonMqttClient instance.
161
- """
162
138
  mqtt_client = await LGHorizonMqttClient.create(
163
139
  self.auth,
164
140
  self._on_mqtt_connected,
@@ -168,10 +144,8 @@ class LGHorizonApi:
168
144
 
169
145
  async def _on_mqtt_connected(self):
170
146
  """MQTT connected callback."""
171
- await self._mqtt_client.subscribe("#")
172
147
  await self._mqtt_client.subscribe(self.auth.household_id)
173
148
  # await self._mqtt_client.subscribe(self.auth.household_id + "/#")
174
- # await self._mqtt_client.subscribe(self.auth.household_id + "/+/#")
175
149
  await self._mqtt_client.subscribe(
176
150
  self.auth.household_id + "/" + self._mqtt_client.client_id
177
151
  )
@@ -203,16 +177,12 @@ class LGHorizonApi:
203
177
  case LGHorizonMessageType.STATUS:
204
178
  message.__class__ = LGHorizonStatusMessage
205
179
  status_message = cast(LGHorizonStatusMessage, message)
206
- device = self._devices.get(status_message.source, None)
207
- if not device:
208
- return
180
+ device = self._devices[status_message.source]
209
181
  await device.handle_status_message(status_message)
210
182
  case LGHorizonMessageType.UI_STATUS:
211
183
  message.__class__ = LGHorizonUIStatusMessage
212
184
  ui_status_message = cast(LGHorizonUIStatusMessage, message)
213
- device = self._devices.get(ui_status_message.source, None)
214
- if not device:
215
- return
185
+ device = self._devices[ui_status_message.source]
216
186
  if (
217
187
  not device.device_state.state
218
188
  == LGHorizonRunningState.ONLINE_RUNNING
@@ -220,7 +190,7 @@ class LGHorizonApi:
220
190
  return
221
191
  await device.handle_ui_status_message(ui_status_message)
222
192
 
223
- async def _get_customer_info(self) -> LGHorizonCustomer:
193
+ async def _get_customer_info(self) -> Any:
224
194
  service_url = await self._service_config.get_service_url(
225
195
  "personalizationService"
226
196
  )
@@ -274,14 +244,14 @@ class LGHorizonApi:
274
244
 
275
245
  async def get_show_recordings(
276
246
  self, show_id: str, channel_id: str
277
- ) -> LGHorizonShowRecordingList: # type: ignore[valid-type]
247
+ ) -> LGHorizonRecordingList:
278
248
  """Retrieve all recordings."""
279
249
  _LOGGER.debug("Retrieving recordings fro show...")
280
250
  service_url = await self._service_config.get_service_url("recordingService")
281
251
  lang = await self._customer.get_profile_lang(self._profile_id)
282
252
  episodes_json = await self.auth.request(
283
253
  service_url,
284
- f"/customers/{self.auth.household_id}/episodes/shows/{show_id}?source=recording&isAdult=false&offset=0&limit=100&profileId={self._profile_id}&language={lang}&channelId={channel_id}&sort=time&sortOrder=asc",
254
+ f"/customers/8436830_nl/episodes/shows/{show_id}?source=recording&isAdult=false&offset=0&limit=100&profileId={self._profile_id}&language={lang}&channelId={channel_id}&sort=time&sortOrder=asc",
285
255
  )
286
256
  recordings = await self._recording_factory.create_episodes(episodes_json)
287
257
  return recordings
@@ -1,6 +1,6 @@
1
1
  "LG Horizon Message Factory."
2
2
 
3
- from .lghorizon_models import (
3
+ from .models.lghorizon_message import (
4
4
  LGHorizonMessage,
5
5
  LGHorizonStatusMessage,
6
6
  LGHorizonUnknownMessage,
@@ -22,6 +22,7 @@ class LGHorizonMessageFactory:
22
22
  case LGHorizonMessageType.STATUS:
23
23
  return LGHorizonStatusMessage(payload, topic)
24
24
  case LGHorizonMessageType.UI_STATUS:
25
+ # Placeholder for UI_STATUS message handling
25
26
  return LGHorizonUIStatusMessage(payload, topic)
26
27
  case LGHorizonMessageType.UNKNOWN:
27
28
  return LGHorizonUnknownMessage(payload, topic)
@@ -1,11 +1,9 @@
1
- from typing import Optional
2
- from .lghorizon_models import (
1
+ from .models.lghorizon_recordings import (
3
2
  LGHorizonRecordingList,
4
3
  LGHorizonRecordingSingle,
5
4
  LGHorizonRecordingSeason,
6
5
  LGHorizonRecordingShow,
7
6
  LGHorizonRecordingType,
8
- LGHorizonShowRecordingList,
9
7
  )
10
8
 
11
9
 
@@ -34,22 +32,10 @@ class LGHorizonRecordingFactory:
34
32
 
35
33
  return LGHorizonRecordingList(recording_list)
36
34
 
37
- async def create_episodes(self, episode_json: dict) -> LGHorizonShowRecordingList:
35
+ async def create_episodes(self, episode_json: dict) -> LGHorizonRecordingList:
38
36
  """Create a LGHorizonRecording list based for episodes."""
39
37
  recording_list = []
40
- show_title: Optional[str] = None
41
- if "images" in episode_json:
42
- images = episode_json["images"]
43
- show_image = next(
44
- (img["url"] for img in images if img.get("type") == "titleTreatment"),
45
- images[0]["url"] if images else None,
46
- )
47
- else:
48
- show_image = None
49
-
50
38
  for recording in episode_json["data"]:
51
39
  recording_single = LGHorizonRecordingSingle(recording)
52
- if show_title is None:
53
- show_title = recording_single.show_title or recording_single.title
54
40
  recording_list.append(recording_single)
55
- return LGHorizonShowRecordingList(show_title, show_image, recording_list)
41
+ return LGHorizonRecordingList(recording_list)
@@ -0,0 +1,41 @@
1
+ Metadata-Version: 2.4
2
+ Name: lghorizon
3
+ Version: 0.9.0.dev1
4
+ Summary: Python client for Liberty Global Horizon settop boxes
5
+ Home-page: https://github.com/sholofly/LGHorizon-python
6
+ Author: Rudolf Offereins
7
+ Author-email: r.offereins@gmail.com
8
+ License: MIT license
9
+ Keywords: LG,Horizon,API,Settop box
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Natural Language :: English
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Programming Language :: Python :: 3.6
17
+ Classifier: Programming Language :: Python :: 3.7
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: paho-mqtt
24
+ Requires-Dist: requests>=2.22.0
25
+ Requires-Dist: backoff>=1.9.0
26
+ Dynamic: author
27
+ Dynamic: author-email
28
+ Dynamic: classifier
29
+ Dynamic: description
30
+ Dynamic: description-content-type
31
+ Dynamic: home-page
32
+ Dynamic: keywords
33
+ Dynamic: license
34
+ Dynamic: license-file
35
+ Dynamic: requires-dist
36
+ Dynamic: requires-python
37
+ Dynamic: summary
38
+
39
+ # LG Horizon Api
40
+
41
+ Python library to control multiple LG Horizon boxes
@@ -0,0 +1,13 @@
1
+ lghorizon/__init__.py,sha256=Hv5lGe6Nb0OlkugLpNA0gyIPFRHOGkdnUvhLS0Sn0eA,863
2
+ lghorizon/const.py,sha256=HINlbyevEN9ZRnfIBbSGNc6i9J8WkIgpqkLZrwyqpGQ,5307
3
+ lghorizon/device_state_processor.py,sha256=MuItTJoXDUeSXHW5QjmPjbdQ72JFBGLWfuo6iMKOTYk,12141
4
+ lghorizon/helpers.py,sha256=SGlEN6V0kh2vqw1qCKmM1KhfeO-UvPyyQmnThgFLFhs,272
5
+ lghorizon/lghorizonapi.py,sha256=eZmcIlbA_Xgtcq65ShVSiBXAapFdAVUIxYuBOKVV8h8,11841
6
+ lghorizon/message_factory.py,sha256=Bk0k6fZSJNgpmcN_IxPL26lwc6V1fCbQe7acd65Km0g,1504
7
+ lghorizon/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ lghorizon/recording_factory.py,sha256=xcEVzchn2SSV1ojRo9N17VfaEDlD9AaYLEo92uNNgaA,1766
9
+ lghorizon-0.9.0.dev1.dist-info/licenses/LICENSE,sha256=6Dh2tur1gMX3r3rITjVwUONBEJxyyPZDY8p6DZXtimE,1059
10
+ lghorizon-0.9.0.dev1.dist-info/METADATA,sha256=zwM_v9XJf8B7v5H32jxRv3Qpt_aphskTKturNLIcnk4,1287
11
+ lghorizon-0.9.0.dev1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
12
+ lghorizon-0.9.0.dev1.dist-info/top_level.txt,sha256=usii76_AxGfPI6gjrrh-NyZxcQQuF1B8_Q9kd7sID8Q,10
13
+ lghorizon-0.9.0.dev1.dist-info/RECORD,,
lghorizon/exceptions.py DELETED
@@ -1,17 +0,0 @@
1
- """Exceptions for the LGHorizon API."""
2
-
3
-
4
- class LGHorizonApiError(Exception):
5
- """Generic LGHorizon exception."""
6
-
7
-
8
- class LGHorizonApiConnectionError(LGHorizonApiError):
9
- """Exception for connection-related errors with the LG Horizon API."""
10
-
11
-
12
- class LGHorizonApiUnauthorizedError(Exception):
13
- """Exception for unauthorized access to the LG Horizon API."""
14
-
15
-
16
- class LGHorizonApiLockedError(LGHorizonApiUnauthorizedError):
17
- """Exception for locked account errors with the LG Horizon API."""