lghorizon 0.7.2__py3-none-any.whl → 0.7.3b1__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 +16 -2
- lghorizon/lghorizon_api.py +28 -14
- lghorizon/models.py +18 -3
- {lghorizon-0.7.2.dist-info → lghorizon-0.7.3b1.dist-info}/METADATA +1 -1
- lghorizon-0.7.3b1.dist-info/RECORD +12 -0
- lghorizon-0.7.2.dist-info/RECORD +0 -12
- {lghorizon-0.7.2.dist-info → lghorizon-0.7.3b1.dist-info}/LICENSE +0 -0
- {lghorizon-0.7.2.dist-info → lghorizon-0.7.3b1.dist-info}/WHEEL +0 -0
- {lghorizon-0.7.2.dist-info → lghorizon-0.7.3b1.dist-info}/top_level.txt +0 -0
lghorizon/__init__.py
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
"""Python client for LG Horizon."""
|
|
2
|
+
|
|
2
3
|
from .lghorizon_api import LGHorizonApi
|
|
3
|
-
from .models import
|
|
4
|
+
from .models import (
|
|
5
|
+
LGHorizonBox,
|
|
6
|
+
LGHorizonRecordingListSeasonShow,
|
|
7
|
+
LGHorizonRecordingSingle,
|
|
8
|
+
LGHorizonRecordingShow,
|
|
9
|
+
LGHorizonRecordingEpisode,
|
|
10
|
+
LGHorizonCustomer,
|
|
11
|
+
)
|
|
4
12
|
from .exceptions import LGHorizonApiUnauthorizedError, LGHorizonApiConnectionError
|
|
5
|
-
from .const import
|
|
13
|
+
from .const import (
|
|
14
|
+
ONLINE_RUNNING,
|
|
15
|
+
ONLINE_STANDBY,
|
|
16
|
+
RECORDING_TYPE_SHOW,
|
|
17
|
+
RECORDING_TYPE_SEASON,
|
|
18
|
+
RECORDING_TYPE_SINGLE,
|
|
19
|
+
) # noqa
|
lghorizon/lghorizon_api.py
CHANGED
|
@@ -47,7 +47,7 @@ class LGHorizonApi:
|
|
|
47
47
|
_auth: LGHorizonAuth = None
|
|
48
48
|
_session: Session = None
|
|
49
49
|
settop_boxes: Dict[str, LGHorizonBox] = None
|
|
50
|
-
|
|
50
|
+
customer: LGHorizonCustomer = None
|
|
51
51
|
_mqttClient: LGHorizonMqttClient = None
|
|
52
52
|
_channels: Dict[str, LGHorizonChannel] = None
|
|
53
53
|
_country_settings = None
|
|
@@ -57,6 +57,7 @@ class LGHorizonApi:
|
|
|
57
57
|
_identifier: str = None
|
|
58
58
|
_config: str = None
|
|
59
59
|
_refresh_callback: Callable = None
|
|
60
|
+
_profile_id: str = None
|
|
60
61
|
|
|
61
62
|
def __init__(
|
|
62
63
|
self,
|
|
@@ -65,6 +66,7 @@ class LGHorizonApi:
|
|
|
65
66
|
country_code: str = "nl",
|
|
66
67
|
identifier: str = None,
|
|
67
68
|
refresh_token=None,
|
|
69
|
+
profile_id=None,
|
|
68
70
|
) -> None:
|
|
69
71
|
"""Create LGHorizon API."""
|
|
70
72
|
self.username = username
|
|
@@ -78,6 +80,7 @@ class LGHorizonApi:
|
|
|
78
80
|
self._channels = {}
|
|
79
81
|
self._entitlements = []
|
|
80
82
|
self._identifier = identifier
|
|
83
|
+
self._profile_id = profile_id
|
|
81
84
|
|
|
82
85
|
@backoff.on_exception(
|
|
83
86
|
backoff.expo, LGHorizonApiConnectionError, max_tries=3, logger=_logger
|
|
@@ -149,7 +152,7 @@ class LGHorizonApi:
|
|
|
149
152
|
self._session.cookies["ACCESSTOKEN"] = self._auth.accessToken
|
|
150
153
|
|
|
151
154
|
if self._refresh_callback:
|
|
152
|
-
self._refresh_callback
|
|
155
|
+
self._refresh_callback()
|
|
153
156
|
|
|
154
157
|
_logger.debug("Authorization succeeded")
|
|
155
158
|
|
|
@@ -246,6 +249,7 @@ class LGHorizonApi:
|
|
|
246
249
|
self._on_mqtt_connected,
|
|
247
250
|
self._on_mqtt_message,
|
|
248
251
|
)
|
|
252
|
+
|
|
249
253
|
self._register_customer_and_boxes()
|
|
250
254
|
self._mqttClient.connect()
|
|
251
255
|
|
|
@@ -265,7 +269,7 @@ class LGHorizonApi:
|
|
|
265
269
|
def _on_mqtt_message(self, message: str, topic: str) -> None:
|
|
266
270
|
if "source" in message:
|
|
267
271
|
deviceId = message["source"]
|
|
268
|
-
if not isinstance(deviceId,str):
|
|
272
|
+
if not isinstance(deviceId, str):
|
|
269
273
|
_logger.debug("ignoring message - not a string")
|
|
270
274
|
return
|
|
271
275
|
if not deviceId in self.settop_boxes.keys():
|
|
@@ -346,7 +350,7 @@ class LGHorizonApi:
|
|
|
346
350
|
last_speed_change_time = playerState["lastSpeedChangeTime"]
|
|
347
351
|
relative_position = playerState["relativePosition"]
|
|
348
352
|
raw_vod = self._do_api_call(
|
|
349
|
-
f"{self._config['vodService']['URL']}/v2/detailscreen/{titleId}?language={self._country_settings['language']}&profileId=4504e28d-c1cb-4284-810b-f5eaab06f034&cityId={self.
|
|
353
|
+
f"{self._config['vodService']['URL']}/v2/detailscreen/{titleId}?language={self._country_settings['language']}&profileId=4504e28d-c1cb-4284-810b-f5eaab06f034&cityId={self.customer.cityId}"
|
|
350
354
|
)
|
|
351
355
|
vod = LGHorizonVod(raw_vod)
|
|
352
356
|
self.settop_boxes[deviceId].update_with_vod(
|
|
@@ -378,36 +382,43 @@ class LGHorizonApi:
|
|
|
378
382
|
personalisation_result = self._do_api_call(
|
|
379
383
|
f"{self._config['personalizationService']['URL']}/v1/customer/{self._auth.householdId}?with=profiles%2Cdevices"
|
|
380
384
|
)
|
|
381
|
-
_logger.debug(
|
|
382
|
-
self.
|
|
385
|
+
_logger.debug("Personalisation result: %s ", personalisation_result)
|
|
386
|
+
self.customer = LGHorizonCustomer(personalisation_result)
|
|
383
387
|
self._get_channels()
|
|
384
|
-
if
|
|
388
|
+
if "assignedDevices" not in personalisation_result:
|
|
385
389
|
_logger.warning("No boxes found.")
|
|
386
390
|
return
|
|
387
391
|
_logger.info("Registering boxes")
|
|
388
|
-
for device in
|
|
392
|
+
for device in self.customer.settop_boxes:
|
|
389
393
|
platform_type = device["platformType"]
|
|
390
|
-
if not
|
|
394
|
+
if platform_type not in _supported_platforms:
|
|
391
395
|
continue
|
|
392
396
|
if (
|
|
393
397
|
"platform_types" in self._country_settings
|
|
394
398
|
and platform_type in self._country_settings["platform_types"]
|
|
395
399
|
):
|
|
396
|
-
|
|
400
|
+
platform_type = self._country_settings["platform_types"][platform_type]
|
|
397
401
|
else:
|
|
398
|
-
|
|
402
|
+
platform_type = None
|
|
399
403
|
box = LGHorizonBox(
|
|
400
|
-
device,
|
|
404
|
+
device, platform_type, self._mqttClient, self._auth, self._channels
|
|
401
405
|
)
|
|
402
406
|
self.settop_boxes[box.deviceId] = box
|
|
403
|
-
_logger.info(
|
|
407
|
+
_logger.info("Box %s registered...", box.deviceId)
|
|
404
408
|
|
|
405
409
|
def _get_channels(self):
|
|
406
410
|
self._update_entitlements()
|
|
407
411
|
_logger.info("Retrieving channels...")
|
|
408
412
|
channels_result = self._do_api_call(
|
|
409
|
-
f"{self._config['linearService']['URL']}/v2/channels?cityId={self.
|
|
413
|
+
f"{self._config['linearService']['URL']}/v2/channels?cityId={self.customer.cityId}&language={self._country_settings['language']}&productClass=Orion-DASH"
|
|
410
414
|
)
|
|
415
|
+
profile_channels = []
|
|
416
|
+
if self._profile_id and self._profile_id in self.customer.profiles:
|
|
417
|
+
profile_channels = self.customer.profiles[
|
|
418
|
+
self._profile_id
|
|
419
|
+
].favorite_channels
|
|
420
|
+
|
|
421
|
+
has_profile_channels = len(profile_channels) > 0
|
|
411
422
|
for channel in channels_result:
|
|
412
423
|
if "isRadio" in channel and channel["isRadio"]:
|
|
413
424
|
continue
|
|
@@ -417,6 +428,9 @@ class LGHorizonApi:
|
|
|
417
428
|
if len(common_entitlements) == 0:
|
|
418
429
|
continue
|
|
419
430
|
channel_id = channel["id"]
|
|
431
|
+
if has_profile_channels and channel_id not in profile_channels:
|
|
432
|
+
continue
|
|
433
|
+
|
|
420
434
|
self._channels[channel_id] = LGHorizonChannel(channel)
|
|
421
435
|
_logger.info(f"{len(self._channels)} retrieved.")
|
|
422
436
|
|
lghorizon/models.py
CHANGED
|
@@ -677,17 +677,32 @@ class LGHorizonBox:
|
|
|
677
677
|
self._mqtt_client.publish_message(topic, json.dumps(payload))
|
|
678
678
|
|
|
679
679
|
|
|
680
|
+
class LGHorizonProfile:
|
|
681
|
+
profile_id: str = None
|
|
682
|
+
name: str = None
|
|
683
|
+
favorite_channels: [] = None
|
|
684
|
+
|
|
685
|
+
def __init__(self, json_payload):
|
|
686
|
+
self.profile_id = json_payload["profileId"]
|
|
687
|
+
self.name = json_payload["name"]
|
|
688
|
+
self.favorite_channels = json_payload["favoriteChannels"]
|
|
689
|
+
|
|
690
|
+
|
|
680
691
|
class LGHorizonCustomer:
|
|
681
692
|
customerId: str = None
|
|
682
693
|
hashedCustomerId: str = None
|
|
683
694
|
countryId: str = None
|
|
684
695
|
cityId: int = 0
|
|
685
|
-
settop_boxes:
|
|
696
|
+
settop_boxes: [] = None
|
|
697
|
+
profiles: Dict[str, LGHorizonProfile] = {}
|
|
686
698
|
|
|
687
699
|
def __init__(self, json_payload):
|
|
688
700
|
self.customerId = json_payload["customerId"]
|
|
689
701
|
self.hashedCustomerId = json_payload["hashedCustomerId"]
|
|
690
702
|
self.countryId = json_payload["countryId"]
|
|
691
703
|
self.cityId = json_payload["cityId"]
|
|
692
|
-
if
|
|
693
|
-
|
|
704
|
+
if "assignedDevices" in json_payload:
|
|
705
|
+
self.settop_boxes = json_payload["assignedDevices"]
|
|
706
|
+
if "profiles" in json_payload:
|
|
707
|
+
for profile in json_payload["profiles"]:
|
|
708
|
+
self.profiles[profile["profileId"]] = LGHorizonProfile(profile)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
lghorizon/__init__.py,sha256=Vu9KXNPKpZOqZOk1pXdptYzpXNwM77OjlSJNUOpukKQ,502
|
|
2
|
+
lghorizon/const.py,sha256=S8UWatG7JPCqd1zk-iOoILTvFDEj7YhLcEXxLGhyJXs,4755
|
|
3
|
+
lghorizon/exceptions.py,sha256=spEjRvbNdce2fauQiOFromAbV1QcfA0uMUt0nRVnnkM,318
|
|
4
|
+
lghorizon/helpers.py,sha256=ZWpi7B3hBvwGV02KWQQHVyj7FLLUDtIvKc-Iqsj5VHA,263
|
|
5
|
+
lghorizon/lghorizon_api.py,sha256=WyOVTXxvFHv6wj0niA4WxcUEHgLy_2D5Vi3-I00WRQM,21364
|
|
6
|
+
lghorizon/models.py,sha256=lUKUJiebK65l0lfOwAzDvn0fC6UIvvQS6HI6a0ROZ_8,24437
|
|
7
|
+
lghorizon/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
lghorizon-0.7.3b1.dist-info/LICENSE,sha256=6Dh2tur1gMX3r3rITjVwUONBEJxyyPZDY8p6DZXtimE,1059
|
|
9
|
+
lghorizon-0.7.3b1.dist-info/METADATA,sha256=kk5Pb-r7v35saP0gsIqTXIrhaimWoiwCNSKbhohHuVs,1039
|
|
10
|
+
lghorizon-0.7.3b1.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
|
11
|
+
lghorizon-0.7.3b1.dist-info/top_level.txt,sha256=usii76_AxGfPI6gjrrh-NyZxcQQuF1B8_Q9kd7sID8Q,10
|
|
12
|
+
lghorizon-0.7.3b1.dist-info/RECORD,,
|
lghorizon-0.7.2.dist-info/RECORD
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
lghorizon/__init__.py,sha256=_VjVE44ErvJJMnF5QgXdlw_nQzbHZUhGWw5hF40PolQ,426
|
|
2
|
-
lghorizon/const.py,sha256=S8UWatG7JPCqd1zk-iOoILTvFDEj7YhLcEXxLGhyJXs,4755
|
|
3
|
-
lghorizon/exceptions.py,sha256=spEjRvbNdce2fauQiOFromAbV1QcfA0uMUt0nRVnnkM,318
|
|
4
|
-
lghorizon/helpers.py,sha256=ZWpi7B3hBvwGV02KWQQHVyj7FLLUDtIvKc-Iqsj5VHA,263
|
|
5
|
-
lghorizon/lghorizon_api.py,sha256=5jv06pO7vnLd7ddY0ag1KY6ZGqUNKQULlwYRqqJXjFE,20899
|
|
6
|
-
lghorizon/models.py,sha256=yrKlQMnHCy8FHwCel3lcTUEnd7_JQbETqf5yGW3S84o,23893
|
|
7
|
-
lghorizon/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
lghorizon-0.7.2.dist-info/LICENSE,sha256=6Dh2tur1gMX3r3rITjVwUONBEJxyyPZDY8p6DZXtimE,1059
|
|
9
|
-
lghorizon-0.7.2.dist-info/METADATA,sha256=41HST2UBGXTFeSiUe79wb94FlFwpx5qobCFVS7SHC4w,1037
|
|
10
|
-
lghorizon-0.7.2.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
|
11
|
-
lghorizon-0.7.2.dist-info/top_level.txt,sha256=usii76_AxGfPI6gjrrh-NyZxcQQuF1B8_Q9kd7sID8Q,10
|
|
12
|
-
lghorizon-0.7.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|