lghorizon 0.5.14__py3-none-any.whl → 0.6.0__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.
@@ -5,6 +5,7 @@ import sys, traceback
5
5
  from .exceptions import LGHorizonApiUnauthorizedError, LGHorizonApiConnectionError
6
6
  import backoff
7
7
  from requests import Session, exceptions as request_exceptions
8
+ from paho.mqtt.client import WebsocketConnectionError
8
9
  import re
9
10
  from .models import (
10
11
  LGHorizonAuth,
@@ -260,6 +261,7 @@ class LGHorizonApi:
260
261
  self._auth.mqttToken = mqtt_response["token"]
261
262
  _logger.debug(f"MQTT token: {self._auth.mqttToken}")
262
263
 
264
+ @backoff.on_exception(backoff.expo, BaseException, jitter=None, max_time=600, logger=_logger)
263
265
  def connect(self) -> None:
264
266
  _logger.debug("Connect to API")
265
267
  self._authorize()
@@ -295,8 +297,8 @@ class LGHorizonApi:
295
297
  if "status" in message:
296
298
  self._handle_box_update(deviceId, message)
297
299
  except Exception as ex:
298
- _logger.error("Could not handle status message")
299
- _logger.error(f"Full message: {str(message)}")
300
+ _logger.exception("Could not handle status message")
301
+ _logger.warning(f"Full message: {str(message)}")
300
302
  self.settop_boxes[deviceId].playing_info.reset()
301
303
  self.settop_boxes[deviceId].playing_info.set_paused(False)
302
304
  elif "CPE.capacity" in message:
@@ -332,15 +334,21 @@ class LGHorizonApi:
332
334
  self.settop_boxes[deviceId].update_with_replay_event(source_type, replayEvent, channel)
333
335
  elif source_type == BOX_PLAY_STATE_DVR:
334
336
  recordingId = state_source["recordingId"]
337
+ session_start_time = state_source["sessionStartTime"]
338
+ session_end_time = state_source["sessionEndTime"]
339
+ last_speed_change_time = playerState["lastSpeedChangeTime"]
340
+ relative_position = playerState["relativePosition"]
335
341
  raw_recording = self._do_api_call(f"{self._country_settings['api_url']}/eng/web/recording-service/customers/{self._auth.householdId}/details/single/{recordingId}?profileId=4504e28d-c1cb-4284-810b-f5eaab06f034&language={self._country_settings['language']}")
336
342
  recording = LGHorizonRecordingSingle(raw_recording)
337
343
  channel = self._channels[recording.channelId]
338
- self.settop_boxes[deviceId].update_with_recording(source_type, recording, channel)
344
+ self.settop_boxes[deviceId].update_with_recording(source_type, recording, channel,session_start_time, session_end_time, last_speed_change_time, relative_position)
339
345
  elif source_type == BOX_PLAY_STATE_VOD:
340
346
  titleId = state_source["titleId"]
347
+ last_speed_change_time = playerState["lastSpeedChangeTime"]
348
+ relative_position = playerState["relativePosition"]
341
349
  raw_vod = self._do_api_call(f"{self._country_settings['api_url']}/eng/web/vod-service/v2/detailscreen/{titleId}?language={self._country_settings['language']}&profileId=4504e28d-c1cb-4284-810b-f5eaab06f034&cityId={self._customer.cityId}")
342
350
  vod = LGHorizonVod(raw_vod)
343
- self.settop_boxes[deviceId].update_with_vod(source_type, vod)
351
+ self.settop_boxes[deviceId].update_with_vod(source_type, vod, last_speed_change_time, relative_position)
344
352
  elif uiStatus == "apps":
345
353
  app = LGHorizonApp(statusPayload["appsState"])
346
354
  self.settop_boxes[deviceId].update_with_app('app', app)
lghorizon/models.py CHANGED
@@ -66,6 +66,9 @@ class LGHorizonPlayingInfo:
66
66
  source_type: str = None
67
67
  paused: bool = False
68
68
  channel_title: str = None
69
+ duration: float = None
70
+ position: float = None
71
+ last_position_update: datetime = None
69
72
 
70
73
  def __init__(self):
71
74
  """Initialize the playing info."""
@@ -92,8 +95,20 @@ class LGHorizonPlayingInfo:
92
95
  self.image = image
93
96
 
94
97
  def set_source_type(self, source_type):
95
- """Set sourfce type."""
98
+ """Set source type."""
96
99
  self.source_type = source_type
100
+
101
+ def set_duration(self, duration: float):
102
+ """Set duration."""
103
+ self.duration = duration
104
+
105
+ def set_position(self, position: float):
106
+ """Set position."""
107
+ self.position = position
108
+
109
+ def set_last_position_update(self, last_position_update:datetime):
110
+ """Set last position update."""
111
+ self.last_position_update = last_position_update
97
112
 
98
113
  def reset(self):
99
114
  self.channel_id = None
@@ -102,6 +117,9 @@ class LGHorizonPlayingInfo:
102
117
  self.source_type = None
103
118
  self.paused = False
104
119
  self.channel_title = None
120
+ self.duration = None
121
+ self.last_position_update = None
122
+ self.position = None
105
123
 
106
124
  class LGHorizonChannel:
107
125
  """Represent a channel."""
@@ -255,8 +273,10 @@ class LGHorizonRecordingListSeasonShow(LGHorizonBaseRecording):
255
273
  class LGHorizonVod:
256
274
  title:str = None
257
275
  image: str = None
276
+ duration: float = None
258
277
  def __init__(self, vod_json) -> None:
259
278
  self.title = vod_json['title']
279
+ self.duration = vod_json['duration']
260
280
 
261
281
  class LGHorizonApp:
262
282
  title:str = None
@@ -407,20 +427,31 @@ class LGHorizonBox:
407
427
  self.playing_info.set_image(channel.stream_image)
408
428
  self._trigger_callback()
409
429
 
410
- def update_with_recording(self, source_type: str, recording:LGHorizonRecordingSingle, channel: LGHorizonChannel) -> None:
430
+ def update_with_recording(self, source_type: str, recording:LGHorizonRecordingSingle, channel: LGHorizonChannel, start:float, end: float, last_speed_change:float, relative_position: float) -> None:
411
431
  self.playing_info.set_source_type(source_type)
412
432
  self.playing_info.set_channel(channel.id)
413
433
  self.playing_info.set_channel_title(channel.title)
414
434
  self.playing_info.set_title(f"{recording.title}")
415
435
  self.playing_info.set_image(recording.image)
436
+ start_dt = datetime.fromtimestamp(start / 1000.0)
437
+ end_dt = datetime.fromtimestamp(end / 1000.0)
438
+ duration = (end_dt - start_dt).total_seconds()
439
+ self.playing_info.set_duration(duration)
440
+ self.playing_info.set_position(relative_position)
441
+ last_update_dt = datetime.fromtimestamp(last_speed_change / 1000.0)
442
+ self.playing_info.set_last_position_update(last_update_dt)
416
443
  self._trigger_callback()
417
444
 
418
- def update_with_vod(self, source_type: str, vod:LGHorizonVod) -> None:
445
+ def update_with_vod(self, source_type: str, vod:LGHorizonVod, last_speed_change:float, relative_position: float) -> None:
419
446
  self.playing_info.set_source_type(source_type)
420
447
  self.playing_info.set_channel(None)
421
448
  self.playing_info.set_channel_title(None)
422
449
  self.playing_info.set_title(vod.title)
423
450
  self.playing_info.set_image(None)
451
+ self.playing_info.set_duration(vod.duration)
452
+ self.playing_info.set_position(relative_position)
453
+ last_update_dt = datetime.fromtimestamp(last_speed_change / 1000.0)
454
+ self.playing_info.set_last_position_update(last_update_dt)
424
455
  self._trigger_callback()
425
456
 
426
457
  def update_with_app(self, source_type: str, app:LGHorizonApp) -> None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lghorizon
3
- Version: 0.5.14
3
+ Version: 0.6.0
4
4
  Summary: Python client for Liberty Global Horizon settop boxes
5
5
  Home-page: https://github.com/sholofly/LGHorizon-python
6
6
  Author: Rudolf Offereins
@@ -0,0 +1,11 @@
1
+ lghorizon/__init__.py,sha256=_VjVE44ErvJJMnF5QgXdlw_nQzbHZUhGWw5hF40PolQ,426
2
+ lghorizon/const.py,sha256=ffLn2oicPMDEdTBqofnig8tLJ7dd-kzqLr80UwEZj3Y,9706
3
+ lghorizon/exceptions.py,sha256=spEjRvbNdce2fauQiOFromAbV1QcfA0uMUt0nRVnnkM,318
4
+ lghorizon/helpers.py,sha256=ZWpi7B3hBvwGV02KWQQHVyj7FLLUDtIvKc-Iqsj5VHA,263
5
+ lghorizon/lghorizon_api.py,sha256=o1EB22gYtnFrt5hTw3V5zIqOq7dyUHkg1MWjZO92Fcc,22402
6
+ lghorizon/models.py,sha256=35jAU5mIXq8CaimMGZlZq5-EDCd7SSqJJwoQFm_BAiU,22832
7
+ lghorizon-0.6.0.dist-info/LICENSE,sha256=6Dh2tur1gMX3r3rITjVwUONBEJxyyPZDY8p6DZXtimE,1059
8
+ lghorizon-0.6.0.dist-info/METADATA,sha256=mAGM9zAKVTQ6F9-xGmUvSVfC4Kcxn_q-vpQRXkv6vnc,1044
9
+ lghorizon-0.6.0.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
10
+ lghorizon-0.6.0.dist-info/top_level.txt,sha256=usii76_AxGfPI6gjrrh-NyZxcQQuF1B8_Q9kd7sID8Q,10
11
+ lghorizon-0.6.0.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- lghorizon/__init__.py,sha256=_VjVE44ErvJJMnF5QgXdlw_nQzbHZUhGWw5hF40PolQ,426
2
- lghorizon/const.py,sha256=ffLn2oicPMDEdTBqofnig8tLJ7dd-kzqLr80UwEZj3Y,9706
3
- lghorizon/exceptions.py,sha256=spEjRvbNdce2fauQiOFromAbV1QcfA0uMUt0nRVnnkM,318
4
- lghorizon/helpers.py,sha256=ZWpi7B3hBvwGV02KWQQHVyj7FLLUDtIvKc-Iqsj5VHA,263
5
- lghorizon/lghorizon_api.py,sha256=kBdZYsIbFfPo1TYl8RKZoDuIh9OUfB5FyMwp2BF869c,21697
6
- lghorizon/models.py,sha256=TV7utGdGaOTBvglElqHWZ16xyML-GkHaf7EwqUuPCG8,21377
7
- lghorizon-0.5.14.dist-info/LICENSE,sha256=6Dh2tur1gMX3r3rITjVwUONBEJxyyPZDY8p6DZXtimE,1059
8
- lghorizon-0.5.14.dist-info/METADATA,sha256=rVkEFRl50CPHaQpORVi83UbncGOQAZ8Oja5wLUTEcnE,1045
9
- lghorizon-0.5.14.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
10
- lghorizon-0.5.14.dist-info/top_level.txt,sha256=usii76_AxGfPI6gjrrh-NyZxcQQuF1B8_Q9kd7sID8Q,10
11
- lghorizon-0.5.14.dist-info/RECORD,,