PyChromecast 14.0.1__tar.gz → 14.0.3__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.
Files changed (48) hide show
  1. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/PKG-INFO +7 -1
  2. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/PyChromecast.egg-info/PKG-INFO +7 -1
  3. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/README.rst +6 -0
  4. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/const.py +1 -0
  5. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/plex.py +2 -0
  6. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/youtube.py +1 -0
  7. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/socket_client.py +34 -33
  8. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pyproject.toml +1 -1
  9. PyChromecast-14.0.3/requirements.txt +3 -0
  10. PyChromecast-14.0.1/requirements.txt +0 -3
  11. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/LICENSE +0 -0
  12. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/MANIFEST.in +0 -0
  13. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/PyChromecast.egg-info/SOURCES.txt +0 -0
  14. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/PyChromecast.egg-info/dependency_links.txt +0 -0
  15. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/PyChromecast.egg-info/not-zip-safe +0 -0
  16. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/PyChromecast.egg-info/requires.txt +0 -0
  17. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/PyChromecast.egg-info/top_level.txt +0 -0
  18. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/__init__.py +0 -0
  19. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/config.py +0 -0
  20. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/__init__.py +0 -0
  21. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/bbciplayer.py +0 -0
  22. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/bbcsounds.py +0 -0
  23. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/bubbleupnp.py +0 -0
  24. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/dashcast.py +0 -0
  25. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/homeassistant.py +0 -0
  26. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/homeassistant_media.py +0 -0
  27. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/media.py +0 -0
  28. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/multizone.py +0 -0
  29. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/nrkradio.py +0 -0
  30. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/nrktv.py +0 -0
  31. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/receiver.py +0 -0
  32. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/shaka.py +0 -0
  33. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/supla.py +0 -0
  34. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/controllers/yleareena.py +0 -0
  35. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/dial.py +0 -0
  36. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/discovery.py +0 -0
  37. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/error.py +0 -0
  38. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/generated/authority_keys_pb2.py +0 -0
  39. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/generated/authority_keys_pb2.pyi +0 -0
  40. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/generated/cast_channel_pb2.py +0 -0
  41. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/generated/cast_channel_pb2.pyi +0 -0
  42. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/generated/logging_pb2.py +0 -0
  43. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/generated/logging_pb2.pyi +0 -0
  44. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/generated/readme.txt +0 -0
  45. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/models.py +0 -0
  46. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/quick_play.py +0 -0
  47. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/pychromecast/response_handler.py +0 -0
  48. {PyChromecast-14.0.1 → PyChromecast-14.0.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyChromecast
3
- Version: 14.0.1
3
+ Version: 14.0.3
4
4
  Summary: Python module to talk to Google Chromecast.
5
5
  Author-email: Paulus Schoutsen <paulus@paulusschoutsen.nl>
6
6
  Project-URL: Homepage, https://github.com/home-assistant-libs/pychromecast
@@ -192,3 +192,9 @@ work. Without him it would not have been possible!
192
192
 
193
193
  .. _Linux style wildcard: http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm
194
194
  .. _Fred Clift: https://github.com/minektur
195
+
196
+ |ohf-logo|
197
+
198
+ .. |ohf-logo| image:: https://www.openhomefoundation.org/badges/pychromecast.png
199
+ :alt: PyChromecast - A library from the Open Home Foundation
200
+ :target: https://www.openhomefoundation.org/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyChromecast
3
- Version: 14.0.1
3
+ Version: 14.0.3
4
4
  Summary: Python module to talk to Google Chromecast.
5
5
  Author-email: Paulus Schoutsen <paulus@paulusschoutsen.nl>
6
6
  Project-URL: Homepage, https://github.com/home-assistant-libs/pychromecast
@@ -192,3 +192,9 @@ work. Without him it would not have been possible!
192
192
 
193
193
  .. _Linux style wildcard: http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm
194
194
  .. _Fred Clift: https://github.com/minektur
195
+
196
+ |ohf-logo|
197
+
198
+ .. |ohf-logo| image:: https://www.openhomefoundation.org/badges/pychromecast.png
199
+ :alt: PyChromecast - A library from the Open Home Foundation
200
+ :target: https://www.openhomefoundation.org/
@@ -175,3 +175,9 @@ work. Without him it would not have been possible!
175
175
 
176
176
  .. _Linux style wildcard: http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm
177
177
  .. _Fred Clift: https://github.com/minektur
178
+
179
+ |ohf-logo|
180
+
181
+ .. |ohf-logo| image:: https://www.openhomefoundation.org/badges/pychromecast.png
182
+ :alt: PyChromecast - A library from the Open Home Foundation
183
+ :target: https://www.openhomefoundation.org/
@@ -43,6 +43,7 @@ CAST_TYPES = {
43
43
  "nest audio": (CAST_TYPE_AUDIO, MF_GOOGLE),
44
44
  "nest wifi point": (CAST_TYPE_AUDIO, MF_GOOGLE),
45
45
  "bravia 4k vh2": (CAST_TYPE_CHROMECAST, MF_SONY),
46
+ "bravia 4k vh21": (CAST_TYPE_CHROMECAST, MF_SONY),
46
47
  "C4A": (CAST_TYPE_AUDIO, MF_SONY),
47
48
  "JBL Link 10": (CAST_TYPE_AUDIO, MF_JBL),
48
49
  "JBL Link 20": (CAST_TYPE_AUDIO, MF_JBL),
@@ -108,6 +108,8 @@ def media_to_chromecast_command( # pylint: disable=invalid-name, too-many-local
108
108
  dict: Returs a dict formatted correctly to start playback on a Chromecast.
109
109
  """
110
110
 
111
+ machineIdentifier = None
112
+ token = None
111
113
  if media is not None:
112
114
  # Lets set some params for the user if they use plexapi.
113
115
  server: PlexServer = (
@@ -84,6 +84,7 @@ class YouTubeController(QuickPlayController):
84
84
  super().__init__(YOUTUBE_NAMESPACE, APP_YOUTUBE)
85
85
  self.status_update_event = threading.Event()
86
86
  self._timeout = timeout
87
+ self._session = None
87
88
 
88
89
  def start_session_if_none(self) -> None:
89
90
  """
@@ -10,31 +10,31 @@ Without him this would not have been possible.
10
10
  from __future__ import annotations
11
11
 
12
12
  import abc
13
- from dataclasses import dataclass
14
13
  import errno
15
14
  import json
16
15
  import logging
17
- import select
16
+ import selectors
18
17
  import socket
19
18
  import ssl
20
19
  import threading
21
20
  import time
22
21
  from collections import defaultdict
22
+ from dataclasses import dataclass
23
23
  from struct import pack, unpack
24
24
 
25
25
  import zeroconf
26
26
 
27
- from .controllers import CallbackType, BaseController
27
+ from .const import MESSAGE_TYPE, REQUEST_ID, SESSION_ID
28
+ from .controllers import BaseController, CallbackType
28
29
  from .controllers.media import MediaController
29
30
  from .controllers.receiver import CastStatus, CastStatusListener, ReceiverController
30
- from .const import MESSAGE_TYPE, REQUEST_ID, SESSION_ID
31
31
  from .dial import get_host_from_service
32
32
  from .error import (
33
33
  ChromecastConnectionError,
34
34
  ControllerNotRegistered,
35
- UnsupportedNamespace,
36
35
  NotConnected,
37
36
  PyChromecastStopped,
37
+ UnsupportedNamespace,
38
38
  )
39
39
 
40
40
  # pylint: disable-next=no-name-in-module
@@ -64,8 +64,6 @@ CONNECTION_STATUS_FAILED = "FAILED"
64
64
  CONNECTION_STATUS_FAILED_RESOLVE = "FAILED_RESOLVE"
65
65
  # The socket connection was lost and needs to be retried
66
66
  CONNECTION_STATUS_LOST = "LOST"
67
- # Check for select poll method
68
- SELECT_HAS_POLL = hasattr(select, "poll")
69
67
 
70
68
  HB_PING_TIME = 10
71
69
  HB_PONG_TIME = 10
@@ -215,6 +213,11 @@ class SocketClient(threading.Thread, CastStatusListener):
215
213
  self.connecting = True
216
214
  self.first_connection = True
217
215
  self.socket: socket.socket | ssl.SSLSocket | None = None
216
+ self.selector = selectors.DefaultSelector()
217
+ self.wakeup_selector_key = self.selector.register(
218
+ self.socketpair[0], selectors.EVENT_READ
219
+ )
220
+ self.remote_selector_key: selectors.SelectorKey | None = None
218
221
 
219
222
  # dict mapping namespace on Controller objects
220
223
  self._handlers: dict[str, set[BaseController]] = defaultdict(set)
@@ -238,8 +241,10 @@ class SocketClient(threading.Thread, CastStatusListener):
238
241
  tries = self.tries
239
242
 
240
243
  if self.socket is not None:
244
+ self.selector.unregister(self.socket)
241
245
  self.socket.close()
242
246
  self.socket = None
247
+ self.remote_selector_key = None
243
248
 
244
249
  # Make sure nobody is blocking.
245
250
  for callback_function in self._request_callbacks.values():
@@ -288,10 +293,15 @@ class SocketClient(threading.Thread, CastStatusListener):
288
293
  try:
289
294
  if self.socket is not None:
290
295
  # If we retry connecting, we need to clean up the socket again
291
- self.socket.close() # type: ignore[unreachable]
296
+ self.selector.unregister(self.socket) # type: ignore[unreachable]
297
+ self.socket.close()
292
298
  self.socket = None
299
+ self.remote_selector_key = None
293
300
 
294
301
  self.socket = new_socket()
302
+ self.remote_selector_key = self.selector.register(
303
+ self.socket, selectors.EVENT_READ
304
+ )
295
305
  self.socket.settimeout(self.timeout)
296
306
  self._report_connection_status(
297
307
  ConnectionStatus(
@@ -559,20 +569,8 @@ class SocketClient(threading.Thread, CastStatusListener):
559
569
  assert self.socket is not None
560
570
 
561
571
  # poll the socket, as well as the socketpair to allow us to be interrupted
562
- rlist = [self.socket, self.socketpair[0]]
563
572
  try:
564
- if SELECT_HAS_POLL is True:
565
- # Map file descriptors to socket objects because select.select does not support fd > 1024
566
- # https://stackoverflow.com/questions/14250751/how-to-increase-filedescriptors-range-in-python-select
567
- fd_to_socket = {rlist_item.fileno(): rlist_item for rlist_item in rlist}
568
-
569
- poll_obj = select.poll()
570
- for poll_fd in rlist:
571
- poll_obj.register(poll_fd, select.POLLIN)
572
- poll_result = poll_obj.poll(timeout * 1000) # timeout in milliseconds
573
- can_read = [fd_to_socket[fd] for fd, _status in poll_result]
574
- else:
575
- can_read, _, _ = select.select(rlist, [], [], timeout)
573
+ ready = self.selector.select(timeout)
576
574
  except (ValueError, OSError) as exc:
577
575
  self.logger.error(
578
576
  "[%s(%s):%s] Error in select call: %s",
@@ -584,9 +582,10 @@ class SocketClient(threading.Thread, CastStatusListener):
584
582
  self._force_recon = True
585
583
  return 0
586
584
 
585
+ can_read = {key for key, _ in ready}
587
586
  # read message from chromecast
588
587
  message = None
589
- if self.socket in can_read and not self._force_recon:
588
+ if self.remote_selector_key in can_read and not self._force_recon:
590
589
  try:
591
590
  message = self._read_message()
592
591
  except InterruptLoop as exc:
@@ -611,18 +610,17 @@ class SocketClient(threading.Thread, CastStatusListener):
611
610
  if self.stop.is_set():
612
611
  return 1
613
612
  raise
614
- except socket.error:
613
+ except socket.error as exc:
615
614
  self._force_recon = True
616
615
  self.logger.error(
617
- "[%s(%s):%s] Error reading from socket.",
616
+ "[%s(%s):%s] Error reading from socket: %s",
618
617
  self.fn or "",
619
618
  self.host,
620
619
  self.port,
620
+ exc,
621
621
  )
622
- else:
623
- data = _dict_from_message_payload(message)
624
622
 
625
- if self.socketpair[0] in can_read:
623
+ if self.wakeup_selector_key in can_read:
626
624
  # Clear the socket's buffer
627
625
  self.socketpair[0].recv(128)
628
626
 
@@ -635,6 +633,7 @@ class SocketClient(threading.Thread, CastStatusListener):
635
633
  return 0
636
634
 
637
635
  # See if any handlers will accept this message
636
+ data = _dict_from_message_payload(message)
638
637
  self._route_message(message, data)
639
638
 
640
639
  if REQUEST_ID in data and data[REQUEST_ID] in self._request_callbacks:
@@ -652,8 +651,8 @@ class SocketClient(threading.Thread, CastStatusListener):
652
651
  # check if connection is expired
653
652
  reset = False
654
653
  if self._force_recon:
655
- self.logger.warning(
656
- "[%s(%s):%s] Error communicating with socket, resetting connection",
654
+ self.logger.debug(
655
+ "[%s(%s):%s] Forced reconnection",
657
656
  self.fn or "",
658
657
  self.host,
659
658
  self.port,
@@ -661,7 +660,7 @@ class SocketClient(threading.Thread, CastStatusListener):
661
660
  reset = True
662
661
 
663
662
  elif self.heartbeat_controller.is_expired():
664
- self.logger.warning(
663
+ self.logger.info(
665
664
  "[%s(%s):%s] Heartbeat timeout, resetting connection",
666
665
  self.fn or "",
667
666
  self.host,
@@ -767,6 +766,7 @@ class SocketClient(threading.Thread, CastStatusListener):
767
766
 
768
767
  self.socketpair[0].close()
769
768
  self.socketpair[1].close()
769
+ self.selector.close()
770
770
 
771
771
  self.connecting = True
772
772
 
@@ -897,17 +897,18 @@ class SocketClient(threading.Thread, CastStatusListener):
897
897
  else:
898
898
  callback_function(True, None)
899
899
  self.socket.sendall(be_size + msg.SerializeToString())
900
- except socket.error:
900
+ except socket.error as exc:
901
901
  if callback_function:
902
902
  callback_function(False, None)
903
903
  if not no_add_request_id:
904
904
  self._request_callbacks.pop(request_id, None)
905
905
  self._force_recon = True
906
- self.logger.info(
907
- "[%s(%s):%s] Error writing to socket.",
906
+ self.logger.warning(
907
+ "[%s(%s):%s] Error writing to socket: %s",
908
908
  self.fn or "",
909
909
  self.host,
910
910
  self.port,
911
+ exc,
911
912
  )
912
913
  else:
913
914
  if callback_function:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "PyChromecast"
7
- version = "14.0.1"
7
+ version = "14.0.3"
8
8
  description = "Python module to talk to Google Chromecast."
9
9
  readme = "README.rst"
10
10
  authors = [
@@ -0,0 +1,3 @@
1
+ casttube==0.2.1
2
+ protobuf==5.28.2
3
+ zeroconf==0.135.0
@@ -1,3 +0,0 @@
1
- casttube==0.2.1
2
- protobuf==4.25.2
3
- zeroconf==0.131.0
File without changes
File without changes
File without changes