lghorizon 0.9.0.dev3__py3-none-any.whl → 0.9.1__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 +71 -2
- lghorizon/const.py +12 -77
- lghorizon/exceptions.py +3 -3
- lghorizon/lghorizon_api.py +42 -12
- lghorizon/lghorizon_device.py +101 -28
- lghorizon/lghorizon_device_state_processor.py +90 -26
- lghorizon/lghorizon_message_factory.py +0 -1
- lghorizon/lghorizon_models.py +250 -69
- lghorizon/lghorizon_mqtt_client.py +278 -66
- lghorizon/lghorizon_recording_factory.py +16 -2
- lghorizon-0.9.1.dist-info/METADATA +189 -0
- lghorizon-0.9.1.dist-info/RECORD +17 -0
- lghorizon-0.9.0.dev3.dist-info/METADATA +0 -41
- lghorizon-0.9.0.dev3.dist-info/RECORD +0 -17
- {lghorizon-0.9.0.dev3.dist-info → lghorizon-0.9.1.dist-info}/WHEEL +0 -0
- {lghorizon-0.9.0.dev3.dist-info → lghorizon-0.9.1.dist-info}/licenses/LICENSE +0 -0
- {lghorizon-0.9.0.dev3.dist-info → lghorizon-0.9.1.dist-info}/top_level.txt +0 -0
|
@@ -3,6 +3,9 @@
|
|
|
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
|
|
6
9
|
|
|
7
10
|
from typing import cast, Dict, Optional
|
|
8
11
|
|
|
@@ -15,12 +18,10 @@ from .lghorizon_models import (
|
|
|
15
18
|
LGHorizonReplaySource,
|
|
16
19
|
LGHorizonNDVRSource,
|
|
17
20
|
LGHorizonReviewBufferSource,
|
|
21
|
+
LGHorizonRecordingSource,
|
|
18
22
|
)
|
|
19
23
|
from .lghorizon_models import LGHorizonAuth
|
|
20
|
-
from .lghorizon_models import
|
|
21
|
-
LGHorizonReplayEvent,
|
|
22
|
-
LGHorizonVOD,
|
|
23
|
-
)
|
|
24
|
+
from .lghorizon_models import LGHorizonReplayEvent, LGHorizonVOD, LGHorizonVODType
|
|
24
25
|
|
|
25
26
|
from .lghorizon_models import LGHorizonRecordingSingle
|
|
26
27
|
from .lghorizon_models import LGHorizonChannel
|
|
@@ -99,6 +100,9 @@ class LGHorizonDeviceStateProcessor:
|
|
|
99
100
|
return
|
|
100
101
|
await device_state.reset()
|
|
101
102
|
device_state.source_type = player_state.source_type
|
|
103
|
+
device_state.ui_state_type = LGHorizonUIStateType.MAINUI
|
|
104
|
+
device_state.speed = player_state.speed
|
|
105
|
+
|
|
102
106
|
match player_state.source_type:
|
|
103
107
|
case LGHorizonSourceType.LINEAR:
|
|
104
108
|
await self._process_linear_state(device_state, player_state)
|
|
@@ -116,9 +120,10 @@ class LGHorizonDeviceStateProcessor:
|
|
|
116
120
|
device_state: LGHorizonDeviceState,
|
|
117
121
|
apps_state: LGHorizonAppsState,
|
|
118
122
|
) -> None:
|
|
119
|
-
device_state.
|
|
120
|
-
device_state.
|
|
123
|
+
device_state.id = apps_state.id
|
|
124
|
+
device_state.show_title = apps_state.app_name
|
|
121
125
|
device_state.image = apps_state.logo_path
|
|
126
|
+
device_state.ui_state_type = LGHorizonUIStateType.APPS
|
|
122
127
|
|
|
123
128
|
async def _process_linear_state(
|
|
124
129
|
self,
|
|
@@ -140,12 +145,22 @@ class LGHorizonDeviceStateProcessor:
|
|
|
140
145
|
service_path,
|
|
141
146
|
)
|
|
142
147
|
replay_event = LGHorizonReplayEvent(event_json)
|
|
148
|
+
device_state.id = replay_event.event_id
|
|
143
149
|
channel = self._channels[replay_event.channel_id]
|
|
144
150
|
device_state.source_type = source.source_type
|
|
145
|
-
device_state.channel_id = channel.
|
|
151
|
+
device_state.channel_id = channel.id
|
|
146
152
|
device_state.channel_name = channel.title
|
|
147
|
-
device_state.
|
|
148
|
-
device_state.
|
|
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)
|
|
149
164
|
|
|
150
165
|
# Add random number to url to force refresh
|
|
151
166
|
join_param = "?"
|
|
@@ -155,7 +170,6 @@ class LGHorizonDeviceStateProcessor:
|
|
|
155
170
|
f"{channel.stream_image}{join_param}{str(random.randrange(1000000))}"
|
|
156
171
|
)
|
|
157
172
|
device_state.image = image_url
|
|
158
|
-
await device_state.reset_progress()
|
|
159
173
|
|
|
160
174
|
async def _process_reviewbuffer_state(
|
|
161
175
|
self,
|
|
@@ -177,13 +191,20 @@ class LGHorizonDeviceStateProcessor:
|
|
|
177
191
|
service_path,
|
|
178
192
|
)
|
|
179
193
|
replay_event = LGHorizonReplayEvent(event_json)
|
|
194
|
+
device_state.id = replay_event.event_id
|
|
180
195
|
channel = self._channels[replay_event.channel_id]
|
|
181
196
|
device_state.source_type = source.source_type
|
|
182
|
-
device_state.channel_id = channel.
|
|
197
|
+
device_state.channel_id = channel.id
|
|
183
198
|
device_state.channel_name = channel.title
|
|
184
|
-
device_state.
|
|
185
|
-
device_state.
|
|
186
|
-
|
|
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
|
|
187
208
|
# Add random number to url to force refresh
|
|
188
209
|
join_param = "?"
|
|
189
210
|
if join_param in channel.stream_image:
|
|
@@ -192,7 +213,6 @@ class LGHorizonDeviceStateProcessor:
|
|
|
192
213
|
f"{channel.stream_image}{join_param}{str(random.randrange(1000000))}"
|
|
193
214
|
)
|
|
194
215
|
device_state.image = image_url
|
|
195
|
-
await device_state.reset_progress()
|
|
196
216
|
|
|
197
217
|
async def _process_replay_state(
|
|
198
218
|
self,
|
|
@@ -214,15 +234,27 @@ class LGHorizonDeviceStateProcessor:
|
|
|
214
234
|
service_path,
|
|
215
235
|
)
|
|
216
236
|
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
|
|
217
241
|
device_state.source_type = source.source_type
|
|
218
|
-
device_state.channel_id =
|
|
219
|
-
device_state.
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
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
|
+
)
|
|
223
256
|
# Add random number to url to force refresh
|
|
224
257
|
device_state.image = await self._get_intent_image_url(replay_event.event_id)
|
|
225
|
-
await device_state.reset_progress()
|
|
226
258
|
|
|
227
259
|
async def _process_vod_state(
|
|
228
260
|
self,
|
|
@@ -244,11 +276,20 @@ class LGHorizonDeviceStateProcessor:
|
|
|
244
276
|
service_path,
|
|
245
277
|
)
|
|
246
278
|
vod = LGHorizonVOD(vod_json)
|
|
247
|
-
device_state.
|
|
248
|
-
|
|
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
|
+
|
|
249
288
|
device_state.duration = vod.duration
|
|
289
|
+
device_state.last_position_update = int(time.time() * 1000)
|
|
290
|
+
device_state.position = player_state.relative_position
|
|
291
|
+
|
|
250
292
|
device_state.image = await self._get_intent_image_url(vod.id)
|
|
251
|
-
await device_state.reset_progress()
|
|
252
293
|
|
|
253
294
|
async def _process_ndvr_state(
|
|
254
295
|
self, device_state: LGHorizonDeviceState, player_state: LGHorizonPlayerState
|
|
@@ -267,13 +308,36 @@ class LGHorizonDeviceStateProcessor:
|
|
|
267
308
|
service_path,
|
|
268
309
|
)
|
|
269
310
|
recording = LGHorizonRecordingSingle(recording_json)
|
|
270
|
-
device_state.
|
|
271
|
-
device_state.sub_title = recording.full_episode_title
|
|
311
|
+
device_state.id = recording.id
|
|
272
312
|
device_state.channel_id = recording.channel_id
|
|
273
313
|
if recording.channel_id:
|
|
274
314
|
channel = self._channels[recording.channel_id]
|
|
275
315
|
device_state.channel_name = channel.title
|
|
276
316
|
|
|
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
|
+
|
|
277
341
|
async def _get_intent_image_url(self, intent_id: str) -> Optional[str]:
|
|
278
342
|
"""Get intent image url."""
|
|
279
343
|
service_config = await self._auth.get_service_config()
|
|
@@ -22,7 +22,6 @@ 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
|
|
26
25
|
return LGHorizonUIStatusMessage(payload, topic)
|
|
27
26
|
case LGHorizonMessageType.UNKNOWN:
|
|
28
27
|
return LGHorizonUnknownMessage(payload, topic)
|