lghorizon 0.6.12__py3-none-any.whl → 0.7.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.
lghorizon/const.py CHANGED
@@ -1,4 +1,5 @@
1
1
  """Python client for LGHorizon."""
2
+
2
3
  # flake8: noqa
3
4
  # Box states
4
5
  ONLINE_RUNNING = "ONLINE_RUNNING"
@@ -118,9 +119,7 @@ COUNTRY_SETTINGS = {
118
119
  },
119
120
  "gb": {
120
121
  "api_url": "https://spark-prod-gb.gnp.cloud.virgintvgo.virginmedia.com",
121
- "oauth_url": "https://id.virginmedia.com/rest/v40/session/start?protocol=oidc&rememberMe=true",
122
122
  "channels": [],
123
- "oesp_url": "https://prod.oesp.virginmedia.com/oesp/v4/GB/eng/web",
124
123
  "language": "en",
125
124
  },
126
125
  "ie": {
@@ -1,4 +1,5 @@
1
1
  """Python client for LGHorizon."""
2
+
2
3
  import logging
3
4
  import json
4
5
  import sys, traceback
@@ -62,10 +63,12 @@ class LGHorizonApi:
62
63
  password: str,
63
64
  country_code: str = "nl",
64
65
  identifier: str = None,
66
+ refresh_token = None,
65
67
  ) -> None:
66
68
  """Create LGHorizon API."""
67
69
  self.username = username
68
70
  self.password = password
71
+ self.refresh_token = refresh_token
69
72
  self._session = Session()
70
73
  self._country_settings = COUNTRY_SETTINGS[country_code]
71
74
  self._country_code = country_code
@@ -112,92 +115,36 @@ class LGHorizonApi:
112
115
  self._auth.fill(auth_response.json())
113
116
  _logger.debug("Authorization succeeded")
114
117
 
115
- def authorize_gb(self):
116
- try:
117
- login_session = Session()
118
- ####################################
119
- _logger.debug("Step 1 - Get Authorization data")
120
- auth_url = f"{self._country_settings['oesp_url']}/authorization"
121
- auth_response = login_session.get(auth_url)
122
- if not auth_response.ok:
123
- raise LGHorizonApiConnectionError("Can't connect to authorization URL")
124
- auth_response_json = auth_response.json()
125
- auth_session = auth_response_json["session"]
126
- auth_state = auth_session["state"]
127
- authorizationUri = auth_session["authorizationUri"]
128
- authValidityToken = auth_session["validityToken"]
129
- ####################################
130
- _logger.debug("Step 2 - Get Authorization cookie")
131
-
132
- auth_cookie_response = login_session.get(authorizationUri)
133
- if not auth_cookie_response.ok:
134
- raise LGHorizonApiConnectionError("Can't connect to authorization URL")
135
- ####################################
136
- _logger.debug("Step 3 - Login")
137
- payload = {"username": self.username, "credential": self.password}
138
- headers = {"accept": "application/json; charset=UTF-8, */*"}
118
+ def authorize_gb(self) -> None:
119
+ _logger.debug("Authorizing via refresh")
120
+ refresh_url = (f"{self._country_settings['api_url']}/auth-service/v1/authorization/refresh")
121
+ headers = {"content-type": "application/json", "charset": "utf-8"}
122
+ payload = '{"refreshToken":"' + self.refresh_token + '"}'
139
123
 
140
- login_response = login_session.post(
141
- self._country_settings["oauth_url"],
142
- json.dumps(payload),
143
- headers=headers,
144
- allow_redirects=False,
124
+ try:
125
+ auth_response = self._session.post(
126
+ refresh_url, headers=headers, data=payload
145
127
  )
146
- if not login_response.ok:
147
- raise LGHorizonApiConnectionError("Can't connect to authorization URL")
148
-
149
- if not "x-redirect-location" in login_response.headers:
150
- raise LGHorizonApiConnectionError("No redirect location in headers.")
128
+ except Exception as ex:
129
+ raise LGHorizonApiConnectionError("Unknown connection failure") from ex
151
130
 
152
- redirect_url = login_response.headers["x-redirect-location"]
153
- ####################################
154
- _logger.debug("Step 4 - Follow redirect")
155
- redirect_response = login_session.get(redirect_url, allow_redirects=False)
156
- if not "Location" in redirect_response.headers:
157
- raise LGHorizonApiConnectionError("No success url in redirect.")
158
- ####################################
159
- _logger.debug("Step 5 - Extract auth code")
160
- success_url = redirect_response.headers["Location"]
161
- codeMatches = re.findall(r"code=(.*)&", success_url)
162
- if len(codeMatches) == 0:
163
- raise LGHorizonApiConnectionError("No code in redirect headers")
164
- authorizationCode = codeMatches[0]
165
- stateMatches = re.findall(r"state=(.*)", success_url)
166
- if len(codeMatches) == 0:
167
- raise LGHorizonApiConnectionError("No state in redirect headers")
168
- authorizationState = stateMatches[0]
169
- _logger.debug(
170
- f"Auth code: {authorizationCode}, Auth state: {authorizationState}"
171
- )
172
- ####################################
173
- _logger.debug("Step 6 - Post auth data with valid code")
174
- authorization_payload = {
175
- "authorizationGrant": {
176
- "authorizationCode": authorizationCode,
177
- "validityToken": authValidityToken,
178
- "state": authorizationState,
179
- }
180
- }
181
- headers = {
182
- "content-type": "application/json",
183
- }
184
- # VM requires the client to pass the response from /authorization verbatim to /session?token=true
185
- post_authorization_result = login_session.post(
186
- self._country_settings["oesp_url"] + "/authorization",
187
- json.dumps(authorization_payload),
188
- headers=headers,
189
- )
190
- post_session_result = login_session.post(
191
- self._country_settings["oesp_url"] + "/session?token=true",
192
- json.dumps(post_authorization_result.json()),
193
- headers=headers,
194
- )
131
+ if not auth_response.ok:
132
+ _logger.debug("response %s", auth_response)
133
+ error_json = auth_response.json()
134
+ error = None
135
+ if "error" in error_json:
136
+ error = error_json["error"]
137
+ if error and error["statusCode"] == 97401:
138
+ raise LGHorizonApiUnauthorizedError("Invalid credentials")
139
+ elif error:
140
+ raise LGHorizonApiConnectionError(error["message"])
141
+ else:
142
+ raise LGHorizonApiConnectionError("Unknown connection error")
195
143
 
196
- self._auth.fill(post_session_result.json())
197
- self._session.cookies["ACCESSTOKEN"] = self._auth.accessToken
198
- ####################################
199
- except Exception as ex:
200
- pass
144
+ self._auth.fill(auth_response.json())
145
+ self.refresh_token = self._auth.refreshToken
146
+ self._session.cookies["ACCESSTOKEN"] = self._auth.accessToken
147
+ _logger.debug("Authorization succeeded")
201
148
 
202
149
  def authorize_telenet(self):
203
150
  try:
@@ -275,17 +222,6 @@ class LGHorizonApi:
275
222
  self._auth.mqttToken = mqtt_response["token"]
276
223
  _logger.debug(f"MQTT token: {self._auth.mqttToken}")
277
224
 
278
- def _obtain_mqtt_token_gb(self):
279
- _logger.debug("Obtain Virgin GB mqtt token...")
280
- self._session.headers["x-oesp-token"] = self._auth.accessToken
281
- self._session.headers["x-oesp-username"] = self._auth.username
282
-
283
- mqtt_response = self._do_api_call(
284
- f"{self._country_settings['oesp_url']}/tokens/jwt"
285
- )
286
- self._auth.mqttToken = mqtt_response["token"]
287
- _logger.debug(f"MQTT token: {self._auth.mqttToken}")
288
-
289
225
  @backoff.on_exception(
290
226
  backoff.expo, BaseException, jitter=None, max_time=600, logger=_logger
291
227
  )
@@ -293,10 +229,7 @@ class LGHorizonApi:
293
229
  self._config = self._get_config(self._country_code)
294
230
  _logger.debug("Connect to API")
295
231
  self._authorize()
296
- if self._country_code == "gb":
297
- self._obtain_mqtt_token_gb()
298
- else:
299
- self._obtain_mqtt_token()
232
+ self._obtain_mqtt_token()
300
233
  self._mqttClient = LGHorizonMqttClient(
301
234
  self._auth,
302
235
  self._config["mqttBroker"]["URL"],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lghorizon
3
- Version: 0.6.12
3
+ Version: 0.7.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
@@ -20,7 +20,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
20
  Requires-Python: >=3.9
21
21
  Description-Content-Type: text/markdown
22
22
  License-File: LICENSE
23
- Requires-Dist: paho-mqtt >=1.5.0
23
+ Requires-Dist: paho-mqtt <2.0.0
24
24
  Requires-Dist: requests >=2.22.0
25
25
  Requires-Dist: backoff >=1.9.0
26
26
 
@@ -0,0 +1,12 @@
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=FrYrh-4y_CBZGc6_c8S3xFOCLs9xU8KC2mLdHOLqgLc,20252
6
+ lghorizon/models.py,sha256=yrKlQMnHCy8FHwCel3lcTUEnd7_JQbETqf5yGW3S84o,23893
7
+ lghorizon/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ lghorizon-0.7.0.dist-info/LICENSE,sha256=6Dh2tur1gMX3r3rITjVwUONBEJxyyPZDY8p6DZXtimE,1059
9
+ lghorizon-0.7.0.dist-info/METADATA,sha256=b6vgRtvq_yqodGVn2bwU27Z7NM1wMgl-2QlFwLgpibA,1037
10
+ lghorizon-0.7.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
11
+ lghorizon-0.7.0.dist-info/top_level.txt,sha256=usii76_AxGfPI6gjrrh-NyZxcQQuF1B8_Q9kd7sID8Q,10
12
+ lghorizon-0.7.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (75.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,12 +0,0 @@
1
- lghorizon/__init__.py,sha256=_VjVE44ErvJJMnF5QgXdlw_nQzbHZUhGWw5hF40PolQ,426
2
- lghorizon/const.py,sha256=TLiBJ1x35sXy1hDNaTFU5SM_VPWNIfL9kdTSD2-J-zM,4934
3
- lghorizon/exceptions.py,sha256=spEjRvbNdce2fauQiOFromAbV1QcfA0uMUt0nRVnnkM,318
4
- lghorizon/helpers.py,sha256=ZWpi7B3hBvwGV02KWQQHVyj7FLLUDtIvKc-Iqsj5VHA,263
5
- lghorizon/lghorizon_api.py,sha256=99A4bmOJMQCcsnjma-u6qW6PLImX1yfd7XPJZCy7ABA,23636
6
- lghorizon/models.py,sha256=yrKlQMnHCy8FHwCel3lcTUEnd7_JQbETqf5yGW3S84o,23893
7
- lghorizon/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- lghorizon-0.6.12.dist-info/LICENSE,sha256=6Dh2tur1gMX3r3rITjVwUONBEJxyyPZDY8p6DZXtimE,1059
9
- lghorizon-0.6.12.dist-info/METADATA,sha256=CLB7nDrgINEo3L5ODl4TPyh5hvR9l5Y1ppjeH1H3wv8,1039
10
- lghorizon-0.6.12.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
11
- lghorizon-0.6.12.dist-info/top_level.txt,sha256=usii76_AxGfPI6gjrrh-NyZxcQQuF1B8_Q9kd7sID8Q,10
12
- lghorizon-0.6.12.dist-info/RECORD,,