PyChromecast 14.0.5__tar.gz → 14.0.7__tar.gz
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.
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/PKG-INFO +8 -2
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/PyChromecast.egg-info/PKG-INFO +8 -2
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/PyChromecast.egg-info/SOURCES.txt +1 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/const.py +2 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/dial.py +30 -6
- pychromecast-14.0.7/pychromecast/py.typed +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/quick_play.py +1 -1
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/socket_client.py +1 -1
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pyproject.toml +4 -2
- pychromecast-14.0.7/requirements.txt +3 -0
- PyChromecast-14.0.5/requirements.txt +0 -3
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/LICENSE +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/MANIFEST.in +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/PyChromecast.egg-info/dependency_links.txt +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/PyChromecast.egg-info/not-zip-safe +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/PyChromecast.egg-info/requires.txt +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/PyChromecast.egg-info/top_level.txt +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/README.rst +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/__init__.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/config.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/__init__.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/bbciplayer.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/bbcsounds.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/bubbleupnp.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/dashcast.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/heartbeat.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/homeassistant.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/homeassistant_media.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/media.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/multizone.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/nrkradio.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/nrktv.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/plex.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/receiver.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/shaka.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/supla.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/yleareena.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/controllers/youtube.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/discovery.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/error.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/generated/authority_keys_pb2.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/generated/authority_keys_pb2.pyi +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/generated/cast_channel_pb2.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/generated/cast_channel_pb2.pyi +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/generated/logging_pb2.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/generated/logging_pb2.pyi +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/generated/readme.txt +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/models.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/pychromecast/response_handler.py +0 -0
- {PyChromecast-14.0.5 → pychromecast-14.0.7}/setup.cfg +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: PyChromecast
|
|
3
|
-
Version: 14.0.
|
|
3
|
+
Version: 14.0.7
|
|
4
4
|
Summary: Python module to talk to Google Chromecast.
|
|
5
5
|
Author-email: Paulus Schoutsen <paulus@paulusschoutsen.nl>
|
|
6
|
+
License: MIT
|
|
6
7
|
Project-URL: Homepage, https://github.com/home-assistant-libs/pychromecast
|
|
7
8
|
Platform: any
|
|
8
9
|
Classifier: Intended Audience :: Developers
|
|
@@ -11,9 +12,14 @@ Classifier: Operating System :: OS Independent
|
|
|
11
12
|
Classifier: Programming Language :: Python
|
|
12
13
|
Classifier: Programming Language :: Python :: 3
|
|
13
14
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
+
Classifier: Typing :: Typed
|
|
14
16
|
Requires-Python: >=3.11.0
|
|
15
17
|
Description-Content-Type: text/x-rst
|
|
16
18
|
License-File: LICENSE
|
|
19
|
+
Requires-Dist: protobuf>=4.25.1
|
|
20
|
+
Requires-Dist: zeroconf>=0.25.1
|
|
21
|
+
Requires-Dist: casttube>=0.2.0
|
|
22
|
+
Dynamic: license-file
|
|
17
23
|
|
|
18
24
|
pychromecast |Build Status|
|
|
19
25
|
===========================
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: PyChromecast
|
|
3
|
-
Version: 14.0.
|
|
3
|
+
Version: 14.0.7
|
|
4
4
|
Summary: Python module to talk to Google Chromecast.
|
|
5
5
|
Author-email: Paulus Schoutsen <paulus@paulusschoutsen.nl>
|
|
6
|
+
License: MIT
|
|
6
7
|
Project-URL: Homepage, https://github.com/home-assistant-libs/pychromecast
|
|
7
8
|
Platform: any
|
|
8
9
|
Classifier: Intended Audience :: Developers
|
|
@@ -11,9 +12,14 @@ Classifier: Operating System :: OS Independent
|
|
|
11
12
|
Classifier: Programming Language :: Python
|
|
12
13
|
Classifier: Programming Language :: Python :: 3
|
|
13
14
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
+
Classifier: Typing :: Typed
|
|
14
16
|
Requires-Python: >=3.11.0
|
|
15
17
|
Description-Content-Type: text/x-rst
|
|
16
18
|
License-File: LICENSE
|
|
19
|
+
Requires-Dist: protobuf>=4.25.1
|
|
20
|
+
Requires-Dist: zeroconf>=0.25.1
|
|
21
|
+
Requires-Dist: casttube>=0.2.0
|
|
22
|
+
Dynamic: license-file
|
|
17
23
|
|
|
18
24
|
pychromecast |Build Status|
|
|
19
25
|
===========================
|
|
@@ -12,6 +12,7 @@ CAST_TYPE_GROUP = "group"
|
|
|
12
12
|
# Default command timeout
|
|
13
13
|
REQUEST_TIMEOUT = 10.0
|
|
14
14
|
|
|
15
|
+
MF_BOSE = "Bose"
|
|
15
16
|
MF_CANTON = "Canton Elektronik GmbH + Co. KG"
|
|
16
17
|
MF_GOOGLE = "Google Inc."
|
|
17
18
|
MF_HARMAN = "HARMAN International Industries"
|
|
@@ -44,6 +45,7 @@ CAST_TYPES = {
|
|
|
44
45
|
"nest wifi point": (CAST_TYPE_AUDIO, MF_GOOGLE),
|
|
45
46
|
"bravia 4k vh2": (CAST_TYPE_CHROMECAST, MF_SONY),
|
|
46
47
|
"bravia 4k vh21": (CAST_TYPE_CHROMECAST, MF_SONY),
|
|
48
|
+
"Bose Smart Ultra Soundbar": (CAST_TYPE_AUDIO, MF_BOSE),
|
|
47
49
|
"C4A": (CAST_TYPE_AUDIO, MF_SONY),
|
|
48
50
|
"JBL Link 10": (CAST_TYPE_AUDIO, MF_JBL),
|
|
49
51
|
"JBL Link 20": (CAST_TYPE_AUDIO, MF_JBL),
|
|
@@ -5,6 +5,7 @@ Implements the DIAL-protocol to communicate with the Chromecast
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
7
|
from dataclasses import dataclass
|
|
8
|
+
from http import HTTPStatus
|
|
8
9
|
import json
|
|
9
10
|
import logging
|
|
10
11
|
import socket
|
|
@@ -74,6 +75,28 @@ def _get_host_from_zc_service_info(
|
|
|
74
75
|
return (host, port)
|
|
75
76
|
|
|
76
77
|
|
|
78
|
+
def _urlopen(url: str, timeout: float, context: ssl.SSLContext | None) -> Any:
|
|
79
|
+
"""Help open an URL."""
|
|
80
|
+
headers = {"content-type": "application/json"}
|
|
81
|
+
try:
|
|
82
|
+
req = urllib.request.Request(url, headers=headers)
|
|
83
|
+
return urllib.request.urlopen(req, timeout=timeout, context=context)
|
|
84
|
+
except urllib.error.HTTPError as err:
|
|
85
|
+
if err.code != HTTPStatus.FORBIDDEN:
|
|
86
|
+
raise
|
|
87
|
+
# We may be blocked because we're connecting to a hostname specified directly
|
|
88
|
+
# instead of to an IP address resolved by mDNS, cast devices will reject the
|
|
89
|
+
# request when the address is set to the hostname. Do another attempt with an
|
|
90
|
+
# empty host header.
|
|
91
|
+
# Note: This is a simplified approach to not have to deal with name resolution
|
|
92
|
+
# in pychromecast. If devices reject the empty host header we need to do name
|
|
93
|
+
# resolution and instead set the host header to the string version of the IP.
|
|
94
|
+
_LOGGER.debug("Failed to fetch %s, retrying with empty host header", url)
|
|
95
|
+
headers["host"] = ""
|
|
96
|
+
req = urllib.request.Request(url, headers=headers)
|
|
97
|
+
return urllib.request.urlopen(req, timeout=timeout, context=context)
|
|
98
|
+
|
|
99
|
+
|
|
77
100
|
def _get_status(
|
|
78
101
|
services: set[HostServiceInfo | MDNSServiceInfo],
|
|
79
102
|
zconf: zeroconf.Zeroconf | None,
|
|
@@ -90,8 +113,6 @@ def _get_status(
|
|
|
90
113
|
_LOGGER.debug("Resolved service %s to %s", service, host)
|
|
91
114
|
break
|
|
92
115
|
|
|
93
|
-
headers = {"content-type": "application/json"}
|
|
94
|
-
|
|
95
116
|
if secure:
|
|
96
117
|
url = FORMAT_BASE_URL_HTTPS.format(host) + path
|
|
97
118
|
else:
|
|
@@ -101,8 +122,7 @@ def _get_status(
|
|
|
101
122
|
if secure and not has_context:
|
|
102
123
|
context = get_ssl_context()
|
|
103
124
|
|
|
104
|
-
|
|
105
|
-
with urllib.request.urlopen(req, timeout=timeout, context=context) as response:
|
|
125
|
+
with _urlopen(url, timeout, context) as response:
|
|
106
126
|
data = response.read()
|
|
107
127
|
return (host, json.loads(data.decode("utf-8")))
|
|
108
128
|
|
|
@@ -246,7 +266,8 @@ def get_device_info( # pylint: disable=too-many-locals
|
|
|
246
266
|
multizone_supported,
|
|
247
267
|
)
|
|
248
268
|
|
|
249
|
-
except (urllib.error.HTTPError, urllib.error.URLError, OSError, ValueError):
|
|
269
|
+
except (urllib.error.HTTPError, urllib.error.URLError, OSError, ValueError) as err:
|
|
270
|
+
_LOGGER.debug("Failed to get device info for %s: %s (%s)", host, err, type(err))
|
|
250
271
|
return None
|
|
251
272
|
|
|
252
273
|
|
|
@@ -305,7 +326,10 @@ def get_multizone_status(
|
|
|
305
326
|
|
|
306
327
|
return MultizoneStatus(dynamic_groups, groups)
|
|
307
328
|
|
|
308
|
-
except (urllib.error.HTTPError, urllib.error.URLError, OSError, ValueError):
|
|
329
|
+
except (urllib.error.HTTPError, urllib.error.URLError, OSError, ValueError) as err:
|
|
330
|
+
_LOGGER.debug(
|
|
331
|
+
"Failed to get multizone status for %s: %s (%s)", host, err, type(err)
|
|
332
|
+
)
|
|
309
333
|
return None
|
|
310
334
|
|
|
311
335
|
|
|
File without changes
|
|
@@ -287,7 +287,7 @@ class SocketClient(threading.Thread, CastStatusListener):
|
|
|
287
287
|
try:
|
|
288
288
|
if self.socket is not None:
|
|
289
289
|
# If we retry connecting, we need to clean up the socket again
|
|
290
|
-
self.selector.unregister(self.socket)
|
|
290
|
+
self.selector.unregister(self.socket)
|
|
291
291
|
self.socket.close()
|
|
292
292
|
self.socket = None
|
|
293
293
|
self.remote_selector_key = None
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools
|
|
2
|
+
requires = ["setuptools>=65.6,<78.0", "wheel>=0.37.1,<0.46.0"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "PyChromecast"
|
|
7
|
-
version = "14.0.
|
|
7
|
+
version = "14.0.7"
|
|
8
|
+
license = {text = "MIT"}
|
|
8
9
|
description = "Python module to talk to Google Chromecast."
|
|
9
10
|
readme = "README.rst"
|
|
10
11
|
authors = [
|
|
@@ -23,6 +24,7 @@ classifiers=[
|
|
|
23
24
|
"Programming Language :: Python",
|
|
24
25
|
"Programming Language :: Python :: 3",
|
|
25
26
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
27
|
+
"Typing :: Typed",
|
|
26
28
|
]
|
|
27
29
|
|
|
28
30
|
[project.urls]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|